[BZOJ2002] [羅区P3203] [Hnoi2010]バウンスDanfeiヒツジ(LCTメンテナンス鎖長)

luoguポータル

2002:[Hnoi2010]バウンスDanfei羊

制限時間:10秒   メモリ制限:259メガバイトの
提出:16082   解決:8241
[ 送信 ] [ ステータス ] [ 議論 ]

説明

ある日、Lostmonkeyは彼の友人の羊の前で披露するために、彼は少し羊でゲームをプレイするために招待された、超弾性装置を発明しました。ゲーム開始は、Lostmonkeyは、Kiは+ i番目に到達する羊は、i番目のユニットに到達したときに、各デバイスは、それが次のステップKIを再生する、初期弾性係数kiを設定し、n個のデバイスのラインに沿って地面に置きます手段、もしデバイスi番目+ KI、羊Danfeiの存在。羊は、いくつかのシェルがDanfeiます後、それは、i番目のユニットから開始されたときに知ってほしいです。ゲームをより面白くするために、Lostmonkeyは弾性装置の弾性係数を変更することができ、いつでも弾性係数が正の整数です。

入力

最初の行は、n接地デバイスが次の行は、nは正の整数であり、0からN-1であったことを意味表しあり、整数nが含まれ、初期弾性係数が続くは、nことを意味します。第三行は、正の整数mを有し、次のmラインをそれぞれ有する少なくとも二つの数字I、J、I = 1、jは再生Danfeiを開始した後に数回から出力された場合、I = 2またなら正の整数kを入力し、それは、弾性手段のj番目の係数kに変更され表します。データn 20%、M <= 10000、N <= 200000、M <100%のデータ= 100000

出力

i = 1からそれぞれのケースについて、あなたは行ごとに、必要なステップ数をエクスポートする必要があります。

サンプル入力

4
1 2 1 1
3
1 1
2 1 1
1 1

サンプル出力

2
3

ヒント

ソース

溶液

  私たちは、このノードではLCTの内側に書かれた0こんにゃくがあいまいなので、タイトルがゼロから始まる番号が付けされていない、数1-nはハを押してください(霧)、私はパーティーにそれを使うだろう。

  ための各I、K + K [i]は、<IF = N、 K + K [i]は、次にI-考えエッジがある> 、 又は側I->仮想ノードN + 1が存在するように。そして、あなたは、各ノードが1とサイドアウト一つだけを持っていることがわかります、O、あなたはどう思いますか?ツリー内!しかし、ノードn + 1つの側ので、通常の木木(LCTやその使用方法)ではありませんでした。

  次に、クエリのxに対する答えが鎖長のX N + 1で、この事実は、簡単に探し出すだけSZを維持する必要があり、それを分割し、X N + 1になる、その答えは、この時点でルートSZ値であるマイナス1。

  変更操作については、少し長く切っまあそれをリンクしています。

  そこで私は、カジュアルユースCOUTをBZOJすることはできません、であり、この定数インテュイットも大きいです。

コード

#include <ビット/ STDC ++ H>
 使用して 名前空間STDを、
CONSTの INT N = 2E5 + 5 
インラインint型リード(){
     int型のx = 0、W = 0CHAR CH = 0 しばらく W | = CH ==(isdigit(CH)!)' - '、CH = getchar関数();
    一方、(isdigit(CH))X =(X << 1)+(X << 3)+(CH ^ 48)、CH = GETCHAR()。
    リターン? -ワット; X:X 
} 
INT SZ [N]、F [N]、C [N] [ 2 ]。
BOOL RV [N]。
#define液晶C [X] [0]
 の#define RC C [X] [1] 
インラインブール NRT(INT X){ 戻り C [F [X]] [ 0 ] == X || C [F [X] ] [ 1 ] == X;} 
インラインボイド押し上げ(INT X){SZ [X] = SZ [LC] + SZ [RC] + 1 ;} 
インラインボイド REV(INT X){LC ^ = RC ^ = LC ^ = RC; RV [X] ^ = 1 ;} 
インラインボイドプッシュダウン(INT X){ 場合(RV [X])REV(LC)、REV(RC)、RV [X] = 0 ;} 
インラインINT  GETINT X){ 戻り C [F [X]] [ 1 ] == X;} 
インラインボイドリンク(int型のx、int型の Y、int型 D){C [X] [D] = Y、F [Y] = X;}
 ボイド回転(INT X){
     int型、Y = F [X]、Z = F [Y]、D = 取得する(X)。
    もし(NRT(Y))C [Z] [ 取得(Y)] = xで、[X] = F Z。
    リンク(Y、C [x]は[D ^ 1 ]、D)。
    リンク(X、Y、D ^ 1 )。
    突き上げ(Y)、押し上げ(X)。
} 
int型ST [N]、TPと、
無効スプレイ(INT X){
     int型 T = X。
    STは、[TP = 1 ] = Tと、
    一方、(NRT(t))のST [++ TP = T = F [T]。
    一方(TP)プッシュダウン(ST [tp-- ])。
    以下のために(; NRT(x)は、回転(X))
         であれば(NRT(F [X]))を取得(X)^ を取得(F [X])?(x)を回転:回転(F [X])。
} 
ボイドアクセス(INT X){
     ためint型、Y = 0 ; X; X = F [Y = X])、
        スプレイ(X)、C [X] [ 1 ] = yと、上げ底(X)。
} 
のボイドmakert(INT X){アクセス(X)、スプレイ(X)、REV(x);}
 int型 findrt(INT X){ 
    アクセス(X)、スプレイ(X)。
    一方(LC)プッシュダウン(x)は、x = LC。
    スプレイ(X)。リターンのx; 
} 
ボイドリンク(int型のx、int型のY){ 
    makert(X)。もし [X] = F(X ^ findrt(Y))、Y。
} 
ボイドカット(int型のx、int型のY){ 
    makert(X)。
    もし(findrt(Y)== X && F [Y] == X && C [Y] [!0 ])F [Y] = Cを[X] [ 1 ] = 0 、押し上げ(X)。
}
ボイドスプリット(int型のx、int型のY){ 
    makert(X)、アクセス(Y)、スプレイ(Y)。
} 
int型M、N、[N]をk個;
#define(X)分(X + K [X]、N + 1)の
 整数のmain(){ 
    N = 読み取ります()。
    int型 i = 1 K [I] =; iが<= n iは++) )(読み取り、リンク(I)I(へ)。
    M = 読み取ります();
    ながら(M-- ){
         int型のx =リード()、yは読み取ら=()+ 1 もし(X&1 ){ 
            スプリット(Y、N + 1 )。 
            のprintf( " %d個の\ n "、SZ [N + 1 ] - 1 )。
        } 
        { 
            カット(Yへ(Y))。
            K [Y] = 読み取ります(); 
            リンク(Yへ(Y))。  
        } 
    } 
    戻り 0 
}
BZOJ2002

 

  

おすすめ

転載: www.cnblogs.com/gosick/p/11256790.html