[テンプレート]リンクカットツリー(ダイナミック木)LCTの概要 - ロサンゼルスコンセプトペーパー+バレーP3690 [テンプレート]リンクカットツリー(ダイナミック木)(LCT、スプレイ)

説明するアムウェイ大物:

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  GETINT 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 
}

 

おすすめ

転載: www.cnblogs.com/hsez-cyx/p/12287331.html