ある日、アルゴリズムの問題 - 逆順(マージソート、フェンウィックツリー、ディスクリート)

[タイトル]逆にする:https://www.luogu.com.cn/problem/P1908

解決策1:暴力に関する法律のn比較的小さいが、この質問は適用されません。

対処方法2:マージソート。

私たちは、簡単にマージ操作時の逆の順序で検索してくることができます。

私は、現在のノード領域の右側にJポイント、現在のノードの左側の領域にポインティングに注意してください。

[I] <= [j]は、[I]は、より大きい又は右領域に[j]を等しいとき++ちょうど私のように、逆の順序の任意の数を構成するものではありません。

場合、すべてのデータは、[I]> [J] [j]は逆+ =ミッドL + 1の数に[I]は、逆の順序で構成されている以上、左領域に等しい場合、

int型のオーバーフローなので、その合計は、長い長い過ごしました

1の#include <iostreamの>
 2の#include <stdio.hの>
 3の#include <アルゴリズム>
 4  の#define N 500010
 5  使って 名前空間STDを、
6  
7  INT N、[N]、C [N]。
8  長い 長い和= 0 9  ボイドマージ(int型 L、INT R){
 10      場合(L> = R)リターン;
11      INT半ば=(L + R)>> 1、K =ミッド+ 1、T = lが、右=、L =左、R。
12     マージ(L、MID)。
13      マージ(MID + 1 、R)。
14      一方(L <=ミッド&& K <= {r)が
 15          あれば([L] <= [K]){
 16              C [tが++] [L ++ = ]と、
17          }
 18          他の
19              C [tが++] [kは++] =、和+ =(長い 長い)中間- L + 1 20      }
 21      ながら(L <= MID)
 22          C [T ++] = [L ++ ]。
23      一方(K <= r)は
 24         C [tは++] [K ++ = ]と、
25      のために(左++; =右<左26          [左] = C [左]。
27  }
 28  
29  、INT (){主
 30      のscanf(" %d個"、&N)
31      のためにINT iは= 1 ; iが<= N; I ++ 32          のscanf(" %dの"、および[I])。
33      マージ(1 、N)
34      のprintf(" %のLLD " 、合計)。
35      リターン 0 ;
36 }

∠(°ゝ°)!

解決策3:フェンウィックツリー

[I]を参照すると、元の配列であります

我々それぞれ対応しフェンウィックツリーツリー[]における[i]の位置[i]は、プレフィックスとがより小さな表すように、+1であるか、またはその数に等しい、次にI-プレフィックスと逆であります数のため。

そして、......オーバーフロー。

シーケンス内の各数は10 ^ 9を超えていないので、そう、あなたが知っています。

スペースの消費量を削減するために、我々は離散を使用しています。

ソート、および1の代わりに、各数...... nはそれぞれ、ツリーのサイズのみが必要よう<< 2 10 ^ 5、大幅に低減させる消費あろう。

コードは以下の通りであります:

1の#include <iostreamの>
 2の#include <アルゴリズム>
 3の#include <stdio.hの>
 4  の#define N 500010
 5  の#define lowbit(x)はxと-x
 6のtypedef 長い LL。
7  使用して 名前空間はstdを、
8  
9  INT N、B [N]、ツリー[N << 2 ]。
10  構造体ノード{
 11      int型のVal、NUM。
12  } [N]。
13  
14  // インライン作用和定義差不多
15インラインBOOL CMP(ノードA、ノードB){
16      であれば(a.val == b.val)戻り a.num < b.num。
17      リターン a.val < b.val。
18  }
 19  ボイド挿入(int型のx、int型K){
 20      ながら(X <= N){
 21          ツリー[X] + = K。
22          X + = lowbit(X)。
23      }
 24  }
 25 LLクエリ(INT X){
 26      LL ANS = 0 27      一方、(X){
 28          ANS + =ツリー[X];
 29          X - = lowbit(X);
 30      }
 31が     戻りANS;
 32  }
 33である 
34は 、INT (){主
 35      scanfの(" %のD "、およびN-)、
 36      のためにINT I = 1 ; I <= N; I ++ 37          scanfの(" %のD "、A&[I] .val)、A [I] .nu​​m = I;
 38である     // すぎる一部番号、派生オーバーフロー空間防ぐ、離散
39      ソート(Aを+ 1、+ N-A + 1 、CMP);
 40     以下のためにINT iが= 1 ; I <= N; I ++ 41          B [i]は.nu​​m] = I。
42      LL ANS = 0 43      のためにINT iは= 1 ; iが<= N; I ++ ){
 44          インサート(B [i]は、1 )。
45          ANS + = I- クエリ(B [I])。
46      }
 47      のprintf(" %のLLD " 、ANS)。
48      リターン 0 ;
49 }

 

おすすめ

転載: www.cnblogs.com/zyyz1126/p/12611742.html