説明するアムウェイ大物:
LCTの概要 - ロサンゼルスコンセプトペーパー+バレーP3690 [テンプレート]リンクカットツリー(ダイナミック木)(LCT、スプレイ)
トピック転送:[テンプレート]リンクカットツリー(ダイナミック木)(luogu)
説明
ノードの値を変更する権利、さらに縁、枠消し、クエリ二つXOR間の正しい道値上のノードをサポートするデータ構造を書きます
解決
ギャングスターはそれを非常に明確な説明にしました
ここでこんにゃく詳細は(例として、彼のコードに)ピットをジャンプ信じるように簡単にそれを追加
- FA []元のツリーの情報を格納することだけ原点の各スプレー木トラバーサル順序に決定することができ、第一FA [基本スプレー木木]の父さ父親が、スプレイが中断しています
- リンク(x、y)は、Fを書き込む必要があり、[X] = yのではなく、書き込みF [Y] = X、Yは、父親スプレイ、スプレイの情報として記憶されている可能性があり、そしてxは、ツリーのルートであります
- スプレイと回転機能機能と伝統的な書き込み異なる、LCTはより深刻0の治療であることに注意してください
コード(彼らの伝統的な書き込みに頼ることを余儀なく...)Iテンプレート
書式#include <cstdioを> する#include <cstdlib> 書式#include <アルゴリズム> 使用して 名前空間をSTD。 CONST INT N = 1E5 + 10 。 INT FA [N]、CH [N] [ 2 ]。 INT S [N]、D [N]、N、M、OPT、X、Y、REV [N]。 BOOL nroot(INT X) { リターン X == CH [FA [X]] [ 0 ] || X == CH [FA [X]] [ 1 ]。 } INT GET(INT X) { リターン X == CH [FA [X]] [ 1 ]。 } 無効 push_up(int型X) { S [X] = S [CH [X] [ 0 ]] ^ S [CH [X] [ 1 ] ^ D [X]。 } ボイド変化(INT X) { スワップ(CH [X] [ 0 ]、CH [X] [ 1 ])。 REV [X] ^ = 1 ; } ボイド push_down(INT X) { 場合(REV [X]) { 変化(CH [X] [ 0 ])。 変化(CH [X] [ 1 ])。 REV [X] = 0 ; } } ボイド DFS(INT X) { 場合(nroot(X))DFS(FA [X])。 push_down(X)。 } ボイド回転(INT X) { int型、Y = FA [X]、Z = FA [Y]、WH = GET (X)。 もし(nroot(Y))CH [Z] [ GET(Y)] = X。 もし(CH [X] [WH ^ 1 ])FA [CH [X] [WH ^ 1 ] = Y。 CH [Y] [WH] = CH [X] [WH ^ 1 ]。 CH [X] [WH ^ 1 ] = Y。 FA [Y] = X、FA [X] = Z; push_up(Y)、push_up(X)。 } 無効スプレイ(INT X) { DFS(X)。 用(int型、FX = FX ; FA [X]、nroot(X)回転(X)) であれば(nroot(FX))が回転(GET(X)== GET?(FX)FX:X)。 } ボイドアクセス(INT X) { ための(int型、Y = 0 ; X; X = FA [Y = X])、 スプレイ(X)、CH [X] [ 1 ] = Y、push_up(X)。 } ボイド makeroot(INT X) { アクセス(X)、スプレイ(X)。 変更(X) } int型 FindRootで(INT X) { アクセス(X)、スプレイ(X)。 一方、(CH [X] [ 0 ])push_down(x)は、X = CH [X] [ 0 ]。 スプレイ(X)。 戻り値は、X; } ボイドリンク(int型のx、int型のY) { makeroot(X)。 もし(!FindRootで(Y)= X)FA [X] = Y。 } ボイドカット(int型のx、int型のY) { makeroot(X)。 もし(FindRootで(Y)== X && FA [Y] == X &&!CH [Y] [ 0 ]) FA [Y] = CH [X] [ 1 ] = 0 ; } ボイドスプリット(int型のx、int型のY) { makeroot(X)。 アクセス(Y)。 スプレイ(Y)。 } int型のmain() { scanf関数(" %D%D "、&N、&M)。 以下のために(INT iが= 1 ; I <= N; I ++ ) のscanf(" %dの"、&D [I])。 一方、(M-- ) { scanf関数(" %D%D%D "、およびOPT、およびX&Y)。 もし(OPT == 0)スプリット(x、y)と、のprintf(" %D \ n " 、S [Y])。 それ以外の 場合(OPT == 1 )リンク(x、y)は、 そう であれば(OPT == 2 )カット(X、Y) 他スプレイ(X)、D [X] = Y、push_up(X)。 } 戻り 0 。 }