交換の回数バブルソート(フェンウィック木)

交換のバブルソートの数を計算します。

逆数の概念:一つの構成では、大きさの逆の順序で番号の一対の長手方向の位置、すなわち、後者の前の数より大きい数、それらは次いで逆と呼ばれている場合

すべては逆の配置が逆の順序で、この数と呼ばれている合計します。逆順0内のすべての数値の終わりであるので、バブルソート

アイデア

暴力:起こった何のi番目のビットの値を横断しながら、私たちは、VIS []配列のレコードを開くことができます。次いで、(i番目のビットの値)ARR横断[i]は、数のARR [I](すなわち、番号i <jの&& ARR [I] <= ARR [J])未満を与えるように思われます

その後、私はヒット条件ARRの数を得るために減算される現在の長さを使用して[i]を逆の数です。

最適化:各要素[i]がトラバーサル編曲未満であると思われるので、私たちは[i]の条件の数の前に現れるARRレコード配列を開くために願っています(あなたが常に要求を通過する時間を取ることはありません)

そして、シングルポイントの更新のために、間隔を求めると、私たちはフェンウィックツリーデータ構造を助けることができます。したがって、フェンウィックツリーの使用に最適化します。 

操作:

各種の列の数は、逆数の総和が得られる
〔iは、[I]を横切る ] 次に、ビット[i]を加えた対応の値
レコードが出現するごとに、周波数前の値そのものよりも小さく、それ自体が見える
横断する際J [J]フロント番号jを持つ、すなわち、数自体は「ビット[J]番目有する未満
、jの逆数-ビット[j]を

// 交換算出したバブルソートの数:
 // 逆数コンセプト、バブルソートのつまり最後は数字0のすべてを逆転することです
 @ アイデア:和の逆の順序ですべての数の列数を取得する種の数
 // [Iトラバース] [i]は、ビット[i]を加えた対応の値
 //は、各値がより少なく発生する前にそれ自体を記録し、その発生
 // [jは、すなわち、以下トラバーサル前番号j] Jを有し、そのビット[J]の数がある
 @の逆Jの数は-ビット[J] 
の#include <ビット/ STDC ++ H.> の#define IOSのIOSの:: sync_with_stdio(0); cin.tie(0);
 の#define MP make_pair
 #defineし 0受け入れ
 使用して、名前空間、STD 
のtypedef ロングロングLL; 
typedefの符号なしロングロングULLを、
typedefのペア < int型int型
   > PII;
constの ダブルパイ= ACOS( - 1.0 )。
constの ダブル ESP = 1E- 9 const  int型 INF = 0x3f3f3f3f const  int型 MAXN = 1E5 + 7 const  int型 MAXM = 1E6 + 7 const  int型 MOD = 1E9 + 7 const  int型 MAXL = 1E6 + 7 

int型のn;
INTのビット[MAXN]。
INT [MAXN] ARR。
int型VIS [MAXN]。 
//0になるまでバイナリ1の最下位ビットが除去されている最初のIからその和
 // iおよび前の項目
のint SUMは、(int型のI){
     int型 S = 0 ;
     ながら(I> 0 ){ 
        S + = 「ビット[i]は、
        I - = I& - I; 
    } 
    戻りS; 
} 
// 新しい有する単一のポイントは、i番目のビットxを増加し、パワーに対応する最小非ゼロの電力が印加
無効(ADDをint型私は、INT X){
     // 'ビット[I] = X、一点変更
     // I = I +&-iを、
    一方(I <= N-){ 
        'ビット[I] + = X; 
        Iは+ = I& - 私は、
    } 
} 
ボイドは、(解決){
     int型 ANS = 0 INT J = 0 ; J <nであり、j ++ ){ 
        ANS + = J - 和(ARR [J])。
        追加([J] ARR、1 )。
    } 
//暴力的解法
// ため(INT i = 0; iがn <; iは++){ // INT CNT = 0。 // のための(int型J = 0; J <ARR [I]; J ++){ // もし(VIS [J])CNT ++。 // } // ANS + = I - CNT。 // VIS [ARR [I] = 1。 // } のprintf(" %d個の\ n " 、ANS)。 } int型のmain(){ memsetの(VIS、0はsizeof (VIS))。 scanf関数(" %のD "、&N) 以下のためにint型私= 0 ; iがN <; Iは++ ){ scanf関数(" %のD "、およびARR [I])。 } )(解きます。 リターン 0 ; }

おすすめ

転載: www.cnblogs.com/Tianwell/p/11490987.html
おすすめ