まず、コードとして氷なしの誰か少ない氷の少ないアカウントのログインケースに元のモデルを許可し、裸の盗作に直接それをコピーして、最終的には優れた仕事抗議選ばれました!
効果の件名:
配列を増加させるときに個数N(1 <= N <= 5E5)を含むアレイに、交換の回数の最小数、バブルソートの使用を必要とします。
トピック分析:
それはAIとAJの順序は、逆に必要なこれだけの数をバインドされて変化するように配列のいずれか2つ、$ iが<J $と$ AI> AJ $を場合は、交換のために。
二つの方法、マージソートを使用して最初を共有:
アレイの再帰的分割、及びため、ソートマージアレイの両側にプロセスをマージ、配列の最初の要素右、左の残りの要素は、要素のものよりも小さい場合は、プロセスの数の逆の順序で並べ替えをマージすることが可能です取得しました。
以下のコードを共有:
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 typedefの長い 長いLL。 const int型 MAXN = 5E5 + 5 。 int型arrcy [MAXN]、[MAXN] LEF、リグ[MAXN]。 LL ANS = 0 。 空マージ(int型 *、int型、int型); 空マージ(int型 *、int型、int型、int型); INT のmain() { int型N、I。 scanf関数(" %d個"、&N); 用(i = 0 ; iがn <; iは++)のscanf(" %dの"、&arrcy [I])。 マージ(arrcy、0、N- 1 )。 printf(" %LLDする\ n " 、ANS)。 リターン 0 ; } ボイドマージ(INT arrcy []、int型 L、INT R) { 場合(L < R) { int型、M =(L + R)/ 2 。 マージ(arrcy、L、M)。 マージ(arrcy、M + 1 、R)。 (arrcy、L、M、r)をマージします。 } を返します。 } ボイドマージ(INT arrcy []、int型 L、INT M、INT R) { int型 NUM1 = M-L + 1、NUM2 = R- M。 int型I、J。 用(i = 0 ; iはNUM1を<; iは++)LEF [I] = arrcy [L + I]。 用(i = 0 ; iはNUM2を<; iは++)リグ[I] = arrcy [M + 1 + I]; I = 0、J = 0 ; 用(int型のk = 0; kは<R-L + 1 ; kは++ ) { 場合(I> = NUM1 ||(J <NUM2 && LEF [I] <= リグ[J])) { arrcy [L + K] =リグ[J ++ ]。 } 他 { 場合(NUM2> J) ANS + = num2- J。 arrcy [L + K] = LEF [I ++ ]。 } } }
方法2:フェンウィックツリーまたはツリーライン
第1の離散最大から最小のサイズによってソートされた配列、各要素の位置のためにその記録し、その後は元の位置+1、その後の操作位置に第1の演算エレメント1に、大から小に配列要素のサイズを押しそして、つまり、要素の逆の順序の数は、合計することができます。
コードの共有ツリーライン:
#include <ビット/ STDC ++ H> 使用して名前空間STDを、 typedefの長い長いLL。 typedefの長いダブルLD; typedefの符号なしの長い長いULL。 typedefのペア < int型、int型 > PII。 #define担当者(I、x、y)がため(I = xをint型、I yを<; I ++) の#define REPT(I、x、y)がため(I = xをint型、iは= yと<; iは++) の#define PB一back の#define Fiの第一 の#define SE第二 の#define MP make_pair用 の#define DD(X)COUT <<#1 X << "=" << X <<」「。 #define ド(X)COUT <<#1 X << "=" << X << "の\ n"。 #define MES(B)のmemset(A、B、はsizeof A)のconst int型 MAXN = 5E5 + 5 。 PII arrcy [MAXN]。クラスツリー { パブリック: int型のL、R。 LLの合計。 }ツリー[MAXN << 2 ]。ボイドビルド(int型 ID、int型の L、INT R)。 無効アドオン(int型の ID、int型のp、LLのNUM); LLクエリ(int型の ID、int型の L、INT R)。ブール COMP( CONST PII&S1、CONST PII&S2) { 戻り s1.fi> s2.fi ||(s1.fi == s2.fi && s1.se> s2.se)。 } int型のmain() { int型N; scanf関数(" %のD "、&N) REPT(I、1 、N) { arrcy [i]は.SE = I。 scanf関数(" %のD "、&arrcy [I] .fi)。 } ビルド(1、1 、N) LL ANS = 0 。 ソート(arrcy +1、arrcy + 1 + N、COMP)。 REPT(I、1 、N) { ANS + =クエリ(1、1 、arrcy [I] .SE)。 (追加1 arrcy、[I] .SE、1 )。 } のprintf(" %LLDする\ n " 、ANS)。 リターン 0 ; } ボイドビルド(int型 ID、int型の L、INT R) { ツリー[ID] .L = L。 ツリー[ID] .R = R。 ツリー[ID] .SUM =0 ; もし(L == R)のリターン; INT半ば=(L + R)/ 2 。 構築(ID * 2 、L、ミッド)。 ビルド(ID * 2 + 1、中間+ 1 、R)。 } ボイド追加(int型 ID、int型のP、LLのNUM) { 場合(ツリー[ID] .L> = P &&ツリー[ID] .R <= P) { ツリー[ID] .SUM + = NUM。 返します。 } もし(ツリー[ID] .L> P ||ツリー[ID] .R <p)のリターン; もし(ツリーは、[IDは* 2 ] .R> = P)(ID *追加2 、P、NUM)を、 場合(ツリー[ID * 2 + 1 ] .L <= P)は(ID *追加2 + 1 、P、NUM)。 ツリー[ID] .SUM =ツリー[ID * 2 ] .SUM +ツリー[ID * 2 + 1 ] .SUM。 } LLクエリ(int型 ID、int型の L、int型R) { 場合(ツリー[ID] .L> = L &&ツリー[ID] .R <= r)は戻りツリー[ID] .SUM。 もし(ツリー[ID] .L> R ||ツリー[ID] .R <L)戻り 0 ; LL、S = 0; もし(ツリー[ID * 2 ] .R> = L)S + =クエリ(ID * 2 、L、R)。 もし(ツリー[ID * 2 + 1 ] .L <= r)は、S + =クエリ(ID * 2 + 1 、L、R)。 リターン秒; }