1552 bzoj

まあスプレイとの最初の維持

クエリがルートに対応するノードを置いたときに続いて、左部分木のサイズがランクされています

その後、間隔を反転することを計画

書式#include <cstdioを> 
する#include <cmath> 
の#include <CStringの> 
の#include <cstdlib> 
書式#include <iostreamの> 
の#include <アルゴリズム> 
書式#include <キュー> 
の#include <スタック>
 使用して 名前空間はstd;
構造体ノード
{ 
    int型V、NUM。
    フレンドブール 演算子 < (ノードA、ノードB)
    { 
        戻り AV == BV a.num <b.num:AV < BV。
    } 
} P [ 100005 ]。
INTの CH [ 100005 ] [ 2 ]。
int型の SIZ [ 100005 ]。
INT [ 100005 ]。
INT [F 100005 ]。
int型 FL [ 100005 ]。
int型の腐敗。
int型のn;
ボイドプッシュダウン(INT X)
{ 
    場合(FL [X])
    { 
        スワップ(CH [CH [X] [ 0 ] [ 0 ]、CH [[x]はCH [ 0 ] [ 1 ])、FL [CH [ X] [ 0 ]] ^ = 1 ; 
        スワップ(CH [CH [X] [ 1 ] [ 0 ]、CH [CH [X] [ 1 ] [ 1])、FL [CH [X] [ 1 ] ^ = 1 ; 
        FL [X] = 0 ; 
    } 
} 
ボイド更新(INT X)
{ 
    SIZ [X] = SIZ [CH [X] [ 0 ] + SIZ [CH [X] [ 1 ]] + 1 
} 
ボイド回転(INT X)
{ 
    int型、Y = F [X]、Z = F [Y]、K =(CH [Y] [ 1 ] == X)
    CH [Z] [CH [Z] [ 1 ] == Y] = xで、[X] = F Z。
    CH [y]は[K] = CHを[X] [K!]、F [CH [X] [] kは!] = yと; 
    CH [X] [!K] = Y、F [Y] = X。
    アップデート(Y)、更新(X)。
} 
無効 dfs_pushdown(int型x)は
{ 
    場合(!x)が復帰
    dfs_pushdown(F [X])。
    プッシュダウン(X)。
} 
ボイドスプレイ(int型のx、int型ED)
{ 
    dfs_pushdown(X)。
    一方、(![X] = F ED)
    { 
        int型、Y = F [X]、Z = F [Y]。
        もし(!Z = ED)
        { 
            もし、((CH [Y] [ 1 ] == X)^(CH [Z] [ 1 ] == Y))に回転(X)
            そうでなければ(Y)を回転させます。
        } 
        回転(X)
    } 
    もし(!ED)腐れ=のX。
} 
int型 get_pos(int型のx、int型K)
{ 
    プッシュダウン(X)を、
    もし(SIZ [CH [X] [ 0 ]> = K)戻り get_pos(CH [X] [ 0 ]、K)。
    そう であれば(SIZ [CH [X] [ 0 ] + 1 <k)の戻り get_pos(CH [X] [ 1 ]、K- 1 -siz [CH [X] [ 0 ]])。
    他の リターンX; 
} 
int型のスプリット(int型の L、 int型R)
{ 
    INT V1 = get_pos(腐敗、1- 1)、V2 = get_pos(腐敗、R + 1 )。
    スプレイ(V1、0 )、スプレイ(V2、V1)。
    戻り CH [V2]を[ 0 ]。
} 
ボイド rever(int型 L、int型R)
{ 
    int型、P = スプリット(L、R)。
    スワップ(CH [P] [ 0 ]、CH [P] [ 1 ])、FL [P] ^ = 1 ; 
} 
INT buildtree(INT L、のint R、int型のFA)
{ 
    int型ミッド=(L + R)>> 1 
    、F [中間] = [FA]。
    FL [中間] = 0 ;
    もし(L == R){FL [中間] = 0 ; [中間] [CH 0 [中間] [] CHを= 1 ] = 0を SIZ [中間] =。1 ; 戻り[中間]を;}
     もし(L <MID)CH [中間] [ 0 ] = buildtree(L、ミッド1 、MID)。
    他の CH [[中期]] [ 0 ] = 0 ;
    もし(R> MID)CH [中間] [ 1 ] = buildtree(MID + 1 、R、MID)。
    他の CH [[中期]] [ 1 ] = 0 ;
    アップデート([中間])。
    戻る[中期]。
} 
INTクエリ(INT X)
{ 
    スプレイ(X、0 );
    戻り [[X] [CH SIZを0 ]]。
} 
int型のmain()
{ 
    ながら1 
    { 
        scanf関数(" %のD "、&N)
        もし(!n)のリターン 0 ;
        以下のためにint型 i = 1 ; iが<= N; iは++)のscanf(" %dの"、&​​Pを[I] .V)、P [i]は.nu​​m = I。
        ソート(P +  1、P + N + 1 )。
        以下のためにint型 i = 1 ; iが<= N; iは++)[Pを[I] .nu​​m + 1 ] = I + 1 
        [ 1 ] = 1、[N + 2 ] = N + 2 
        腐敗 = buildtree(1、N + 20 );
        以下のためにint型 i = 1 ; iが++; iが<= N 
        { 
            int型 T =クエリ(iは+ 1 )。
            もし(T>ⅰ)rever(I + 1、T + 1); 
            printf(" %dの" 、T)。
        } 
        のprintf(" の\ n " ); 
    } 
    戻り 0 
}

 

おすすめ

転載: www.cnblogs.com/zhangleo/p/11122834.html