P1908逆順 - (フェンウィック木)

https://www.luogu.org/problem/P1908

フェンウィックツリーを使用するのが面倒、ツリーラインを好む(唯一のテンプレートを設定し、ビット操作の本質は理解していない)、という記録フェンウィック木コードがなかったこの質問へのビットを記録している間、彼らは、取得する必要があり、3次元部分順CDQ寝具はフェンウィックツリーの外観を設定します。

問題解決のアイデア:最初、順に元の配列順は、ツリーの配列cに加え、各プレフィックスと数の結果は、現在の番号を逆に求めています。

例えば、データの場合:55,44,22,66,33,11

初期フェンウィックツリーC、クリア。

66-4符号ビットが付加され、配列0,0,0、に添加される1、 0,0、66、それは数以下である前に、逆の数が0、0,0,0フェンウィックツリーCは、 1,0,0;

55-1符号ビットが付加されたアレイに追加され、1、 0,0,1,0,0、それは数より大きくない前55、逆の数が0、フェンウィックツリーCは、1,1,0であります2,0,0;

2ビット目に44を追加し、アレイが1加算される、1、 0,1,0,0、44、それは55よりも大きくなる前に、逆の数が1、配列Cが1,2,0,3木であります、0,0

33-5符号ビットが付加され、アレイ1,1,0,1に追加され、1 0;それは数に逆になる前55,44,66が33よりも大きいを有する3、配列Cは、ツリー2 、0,3,1,1

図22は、アレイは、1,1付加され、3位に加え、1 55,44,66は、それが数に逆になる前に22より大きい有し; 1,1,0 2 C 1、2フェンウィックツリーです、 、1,4,1,2

6〜11は、それがアレイ1,1,1,1,1、に追加され、追加される1、前者が11より大きい、それは数に逆され55,44,22,66,33有する5、フェンウィック木Cを1,2,1,4,1,2として

ピット:後者は、第1の演算の逆対を繰り返さないように、追加に従ってソートされた同じ番号が存在する場合。

書式#include <stdio.hに> 
する#include <iostreamの> 
の#include <アルゴリズム> 
書式#include <CStringの> 
書式#include <math.h>の
書式#include < 文字列 > 
の#include <マップ> 
書式#include <キュー> 
の#include <スタック> 
#含む < セット > 
の#include <CTIME>
 の#define LL長い長
 の#define 0x3f3f3f3f INF
 CONST  ダブル PI = 3.1415926 使用して 名前空間はstdを、

const  int型 MAXX = 500005 ;
構造体ノード
{ 
    int型のID;
     int型のValを; 
}; 
ノードA [マックス]; /// オリジナル配列
INT C [マックス]; /// フェンウィックツリー
INT N-; 

BOOL CMP(ノードP1、P2ノード)
{ 
    IF(P1 == p2.val .val)/// ピット
        リターン p1.id> p2.id;
     戻り p1.val> p2.val; 
} 

int型 lowbit(INT X)
{ 
    戻り X&( - X); 
} 

無効に追加し(INT X-、INTヴァル)///VALは位置xの値を追加
{
     ながら(xは<= N + 1/// X 32005未満が別途要求され、惑星のX = 20000多数これらの入力データの左下を見つけることができません
    { 
        C [X] + = ヴァル。
        X + = lowbit(X); 
    } 
} 

int型 SUM(INT X)
{ 
    int型 RES = 0 ;
     一方、(X> 0 
    { 
        RES + = C [X]; 
        X - = lowbit(X); 
    } 
    戻りRES; 
} 



int型のmain()/// P1908
 {
    scanf関数(" %のD "、&N)
    以下のためにint型 i = 1 ; iが<= N; iは++ 
        scanf関数を(" %のD "、および[I] .val)、[I] .ID = I。
    ソート(A + 1、A + N + 1 、CMP)。
    LL ANS = 0 以下のためにint型私= 1 ; iが<= N; iが++ 
    { 
        ANS + = (LL)の和([I] .ID)。
        追加([I] .ID、1 )。
    } 
    のprintf(" %LLDする\ n" 、ANS);
     戻り 0 ; 
}

 

おすすめ

転載: www.cnblogs.com/shoulinniao/p/11619715.html