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からそれぞれのケースについて、あなたは行ごとに、必要なステップ数をエクスポートする必要があります。
サンプル入力
1 2 1 1
3
1 1
2 1 1
1 1
サンプル出力
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 = 0。CHAR 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 GET(INT 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 。 }