芸術バランスツリー(スプレイ)

問題の意味

例えば1,5,4,2として示される配列、Mフリップ動作区間[L、R]は、となる2,4,5,1

最後のシーケンスを探しています

N M 1 0 0 0 0 0

問題の解決策

メンテナンスシーケンスであればウェイト通常のスプレイメンテナンス、そして、あなたは前順が元のシーケンスであるスプレイシーケンスの添字を維持することができます。

スピンルートL-1を置く抽出時間区間[L、R]、R + 1は、ルートの右息子、左部分の二つのサブR + 1に、このセクションにねじ込まれます。

ツリーは構造のいくつかのセクションをで抽出した後、それはセクションには、彼の息子に代わっツリーのルートに交換されようとしているのマークとマーク裏返し。

すべての操作は、このステップを経るため、次のパスマークで、中に見つけることができます。

 

#include <ビット/ STDC ++ H>
 使用して 名前空間STDを、

const  int型 MAXN = 100005 ;
const  int型 OO = 100000000 ;
int型[MAXN]、N、M、根、NUM。
構造体の点{
     int型のサイズ、FA、V、タグ、S [ 2 ]。
} TR [MAXN]。

テンプレート < クラス T>インラインボイドリード(T&X){ 
    X = 0チャー CH = GETCHAR()。
    しばらく(!isdigit(CH))CH = getchar関数();
    一方、(isdigit(CH)){X =(X <<1)+(X << 3)+(CH ^ 48)、CH = GETCHAR();} 
} 

int型のビルド(int型 L、INT R、INT F){
     場合(L> R)戻り 0 ;
    INT今= ++ NUM、ミッド=(L + R)>> 1 
    TR [今]の.Fa = F。
    TR [今] .V = [中期]。
    TR [今] .size ++ ; 
    TR [今] .S [ 0 ] =ビルド(L、ミッド1 今、)。
    TR [今] .S [ 1 ] =ビルド(MID + 1 、R、今)。
    TR [今] .size+ = TR [TR [今] .S [ 1 ]サイズ+ T R [TR [今] .S [ 0 ]]サイズ。
    戻る今; 
} 


ボイドプッシュダウン(INT X){
     場合(!TR [X] .TAG)のリターン; 
    T R [T R [X] .S [ 0 ]タグ^ = 1 ; 
    TR [TR [X] .S [ 1 ]タグ^ = 1 ; 
    スワップ(TR [X] .S [ 0 ]、TR [X] .S [ 1 ])。
    T R [X] .TAG = 0 
} 

INT(見つけるINT X){
     int型今= ルート;
    しばらく1 ){ 
        プッシュダウン(今)。
        場合(X <= TR [TRは今] .S [ 0 ]]サイズ){今TRを= [今] [.S 0 ]。引き続き;} 
        X = X-(TR [今] .Sは、[TR 0サイズ+]。1 )。
        もし(X!)を返すになりました。 TR [今] .S [= 1 ]。
    } 
} 

int型 indenti(INT X){ 戻り .S [TR [X]の.Fa] TR [ 1 ] == X;} 

ボイド接続(int型のx、int型の Y、INT  D){
    TR [X]の.Fa = Y。
    TR [Y] .S [D] =のX。
} 

ボイド更新(INT X){
     int型 LS = T R [X] .S [ 0 ]、RS = T R [X] .S [ 1 ]。
    T R [X] .size = TR [LS] .size + T R [RS] .size + 1 
} 

ボイド回転(INT X){
     int型、F = T R [X]の.Fa、FF = T R [F]の.Fa。
    INT D1 = indenti(X)。
    INT D2 = indenti(F)。
    INTのCS = trの[X] .S [D1 ^ 1 ]。
    (X、FF、D2)を接続します。
    接続(F、X、D1 ^ 1)。
    接続(CS、F、D1)。
    更新(F)
    更新(X)。
} 

ボイドスプレイ(int型のx、int型GO){
     場合ルート=の(==ルート行く)Xと、
    行く =のTRをの.Fa [進みます]。
    一方、(!TR [X]の.Fa = 行く){
         int型、F = T R [X]の.Fa。
        場合(TRの.Fa == [F] (X)を回転移動)。
        そう であれば(indenti(X)== indenti(F)){回転(F)、回転(x);}
         {回転(x)は、回転(x);} 
    } 
} 

ボイド CX(int型のx、int型 Y) {
     int型 L =(X-探す1。 は、R =検索(Y + 1); //は区間[X、Y]先行および後続を見つける
    スプレイ(L、根)、
    スプレイ(R&LT、TR [L]。 Sの[ 1。)];
     int型 TR [ルート] .S = POSを[を1 ]; 
    POS = TR [POS] .S [ 0 ]; // 見つけ[X、Y]全体個ルートサブツリー 
    TR [POS]。 = ^タグ。1 ; 
} 

ボイドニース(INT X){ 
    プッシュダウン(X); 
    IF(TR [X] .S [ 0 ])ニース(TR [X] .S [ 0 ]);
     IF(TR [X]。 !&& V TR = OO [X] .V =! - OO)のprintf(" %のD "、TR [X] .V)。
    もし(T R [X] .S [ 1 ])ニース(TR [X] .S [ 1 ])。
} 

int型のmain(){ 
    (n)を読み出す;(m)を読み出します。
    [ 1 ] = - OO; [N + 2 ] = OO。
    以下のためにint型 i = 1 ; iが<= N; iは++)[I + 1 ] = I。
    ルート =ビルド(1、N + 20 );
    以下のためにint型 I = 1 ; I <= M; iが++ ){
         int型X、Y;(x)を読み出す;(y)を読み出します。
        CX(X + 1、Y +1); // -OO追加
    } 
    ニース(ルート); 
}
コードの表示

 

おすすめ

転載: www.cnblogs.com/sto324/p/11297573.html