アイデアとコードの参照:https://blog.csdn.net/u014800748/article/details/45420085
増加するために、すべての正の整数からなる無限の配列がある: P = {1、2、3、...}。私たちは行わ nは 、この順序でスワップ動作を制御します。 スワップ(、 B)位置に配列の要素を交換する動作であり 、Aおよび B。あなたの仕事は、このようなインデックスペアの数、つまり、結果のシーケンスに反転の数を見つけることです (I、 Jという、) 私は < J と P I > のp jは。
入力
最初の行は、単一の整数含ま N (1≤ nは 10≤ 5の数- ) 配列に適用swapoperationsを。
次の各 n個の ラインが二つの整数含ま I および B I (≤1を I、 bはiは ≦10 9、 I ≠ B Iの引数- ) スワップ操作を。
出力
得られた配列における反転回数 - 単一整数を印刷します。
例
入力
2
4 2
1 4
出力
4
入力
3
1 6
3 4
2 5
出力
15
注意
次のように最初の試料中の配列が変更されています: 。これは、インデックスの組によって形成された4つの反転有する (1,4)、 (2,3)、 (2,4)及び (3、4)。
コード:
#include <cstdioを> する#include <iostreamの> する#include <CStringの> する#include <アルゴリズム> の#include <キュー> の#include <スタック> の#include < 設定 > の#include <ベクトル> の#include <cmath> CONST INT MAXN = 2E5 + 5 ; typedefの長い 長いLL。 使用して 名前空間はstdを、 LL S [MAXN]和[MAXN]。 int型のSS [MAXN]。 INT [MAXN]、[MAXN] B、POS [MAXN] INT lowbit(INT X) { リターンX&( - X)。 } INT N; ボイド更新(int型 POS、int型の広告を) { ながら(POS <= MAXN) { S [POS] + = 広告。 POS + = lowbit(POS)。 } } LL getnum(int型POS)を { LL RES = 0 。 一方、 POS(> 0 ) { RES + = S [POS]。 POS - = lowbit(POS)。 } 戻りRESと、 } INT のmain() { int型のn; 一方、(〜のscanf(" %d個"、&N)) { ため(int型 i = 1 ; iが<= N iが++ ) { scanf関数(" %d個の%のD "、および[I]、&B [i])と; SS [I] = [I]を、 SS [iが Nを+] = Bを[I]。 POS [I] = I。 POS [iが Nを+] = iが+ nは、 } ソート(SS + 1、SS +2 * N + 1 )。 SS [ 0 ] = 0 。 int型 CNT = 0 ; 以下のために(int型 i = 1 ; iが<= 2 * N; I ++ ) 場合(Iの== 1つの || SS [I] = SS [I! - 1 ]) SS [ ++ CNT] = SS [i]は、 和[ 0 ] = 0 。 以下のために(int型 i = 1 ; iは= CNTを<; iは++ ) 和[I] =合計を[I - 1] + SS [I] - SS [I - 1 ] - 1 。 以下のために(int型私= 1 ; iが<= N; iが++ ) { int型 AA = LOWER_BOUND(SS + 1、SS + CNT + 1、[I]) - SS。 INT BB = LOWER_BOUND(SS + 1、SS + CNT + 1、[I] B) - SS。 スワップ(POS [AA]、POS [BB])。 } のmemset(S、0、はsizeof (S))。 LL ANS = 0 。 以下のための(int型I = CNT; 私; i-- ) { ANS + = getnum(POS [I])。 ANS + = ABS(SUM [I] - 和[POS [I])。 アップデート(POS [i]が、1 ); } のprintf(" %LLDする\ n " 、ANS)。 } 戻り 0 。 }