遠い国(D12ツリー・チェーン・スプリット)

問題の意味

パスに、最小限に子供に右を指してポイントをクエリ・ツリーのルートを変更するには、再割り当て:根付いた木を考えると、3つの動作モードがあります

100データの%、N <= 100000、M < = 100000,0 <= <2に所有権の値31です

問題の解決策

あなたはルートを変更しない場合、その後、それは分割ツリーチェーンの素朴な疑問です。

そして、操作方法のルートに変更する?LCT?

どんな効果を有することができるルートの変更を検討し、最初の変更は2点間のルートパスを変更しないであろう、本のパス上の2点が固定されています。

そのサブツリーのために?

 

このようなツリーは、例をとると、その現在のルートのルート= 4と仮定

次いで、これらの点のサブツリーが変更されます:独自のサブツリーは、ツリー全体、経路上の原点のツリーになる彼と第1ルートノード(1,2)、不変のまま。

どのように2番目の変更を考えてみましょう、あなたは彼の息子が、ツリー全体サブツリーマイナスの木、マイナス彼の息子のルートを含むサブツリーとなり見ることができます。

なお、この問題は解決策になることができるように、最小値を選択することは、2つのサブツリーの間隔を差し引くためのDFSに分割されているときに、それが意図され、このような性質です。

#include <ビット/ STDC ++ H>
 使用して 名前空間STDを、
#defineは長い長いっ
 のconst  int型 MAXN = 100005 ;
constの LLのOO = 2100億INTのN、M、nowroot。
INT [MAXN]、AA [MAXN]
int型CNT、ヘッド[MAXN]。
int型 DEP [MAXN]、FA [MAXN] [ 25 ]、サイズ[MAXN]、息子[MAXN]。
INT TOP [MAXN]、ID [MAXN]。
INTの根、LS [MAXN << 1 ]、RS [MAXN << 1 ]。
LL MI [MAXN << 1 ]、タグ[MAXN << 1 ]。
構造体のエッジ{
    int型の次のy; 
} E [MAXN << 1 ]。

テンプレート < クラス T> ボイドリード(T&X){ 
    X = 0チャー CH = GETCHAR()。
    しばらく(!isdigit(CH))CH = getchar関数();
    一方、(isdigit(CH)){X =(X << 1)+(X << 3)+(CH ^ 48)、CH = GETCHAR();} 
} 

LL分(LLのX、LLのY){ 戻り X <Y?X:Y;} 

ボイド追加(int型のx、int型のY){ 
    E [ ++ CNT =(エッジ){Y、ヘッド[X]}。
    ヘッド[X] = CNT。
} 

ボイド DFS(INT U){ 
    サイズ[U] = 1 以下のためにint型 i = 1 ; iは<= 20 ; iは++)FA [U] [I] = FA [FA [U] [I- 1 ]] [I- 1 ]。
    int型 ; I I = I =ヘッド[U] {E [I] .next)
         int型、V = E [I] .Y。
        もし(V == FA [U] [ 0 ])続けます
        FA [V] [ 0 ] = U。
        DEP [V] = DEP [U] +1 ; 
        DFS(V); 
        サイズ[U] + = サイズ[V]。
        もし(サイズ[息子[U] <サイズ[V])息子[U] = V。
    } 
} 

ボイド DFS(INT U、INT TP){ 
    ID [U] = ++ CNT。
    AA [CNTは] = [U]を。
    [U]トップ = TPと、
    もし(!息子[U])のリターン; 
    DFS(息子[U]、TP)。
    int型 ; I I = I =ヘッド[U] {E [I] .next)
         int型、V = E [I] .Y。
        もし(V == FA [U] [ 0] || V ==息子[U])続けます
        DFS(V、V); 
    } 
} 

ボイド更新(INT RT){ 
    MI [RT] = 分(MI [LS [RT]、MI [RS [RT])。
} 

ボイドビルド(INT&RT、int型の L、INT R){ 
    RT = ++ CNT;タグ[RT] = - 1 もし(L == R){MI [RT] = AA [L]。リターン;}
     int型ミッド=(L + R)>> 1 
    ビルド(LS [RT]、L、MID)。
    ビルド(RS [RT]、ミッド + 1 、R)。
    アップデート(RT)。
} 

のボイドput_tag(INT RT、LLヴァル){ 
    MI [RT] =タグ[RT] = ヴァル。
} 

ボイド push_down(INT RT){ 
    put_tag(LS [RT]、タグ[RT])。
    put_tag(RS [RT]、タグ[RT])。
    タグ[RT] = - 1 
} 

ボイドは、(変更INT RT、INT L、INT R、INT a_l、INT A_R、LLヴァル){
     場合(a_l <= 1 && R <= A_R){ 
        put_tag(RT、ヴァル)を、
        返します
    } 
    INT半ば=(L + R)>> 1 もし(タグ[RT] =! - 1 )push_down(RT)。
    もし(a_l <= MID)変更(LS [RT]、L、中間、a_l、A_R、ヴァル)。
    もし(MID <A_R)を変更(RS [RT]、ミッド+ 1 、R、a_l、A_R、ヴァル)。
    アップデート(RT)。
} 

ボイド(変更int型のx、int型のY、LLヴァル){
     一方(上面[X]!= TOP [Y]){
         場合(DEP [TOP [X]]> DEP [トップ[Y])スワップ(Xは、 Y); 
        (変更11 、nは、ID [トップ[Y]、ID [Y]、ヴァル)。
        Y = FA [トップ[Y] [ 0 ]。
    } 
    もし(DEP [X]> DEP [Y])スワップ(X、Y)
    (変更 ANSを。 11 、nは、ID [x]は、ID [Y]、ヴァル)。
} 

LLクエリ(INT RT、INT L、INT R、INT a_l、INT A_R){
     場合(a_l <= 1 && R <= A_R)リターンMI [RT]。
    もし(!タグ[RT] = - 1 )push_down(RT)。
    INT   半ば=(L + R)>> 1 
    LL ANS = OO;
    もし(a_l <= MID)ANS = 分(ANS、クエリ(LS [RT]、L、中間、a_l、A_R))。
    もし(MID <A_R)ANS =分(ANS、クエリ(RS [RT]、ミッド+ 1 、R、a_l、A_R))。
    リターンのmain(){
} 

int型
    (n)を読み出す;(m)を読み出します。
    以下のためにint型 i = 1 ; iがn <; iは++ ){
         int型X、Y。
        読み取り(X)、(Y)を読み出します。
        (x、y)を追加し、(x、y)を加えます。
    } 
    のためにint型 I = 1は iが++; iがn = < 読み出す([I]))。
    (ルート)を読みます。
    DEP [ルート] = 1 
    DFS(ルート)。
    CNT = 0 ; 
    DFS(根、根)。
    CNT = 0 ; 
    ビルド(LS [ 0 ]、1 、N)
    以下のためのint型私は=1 ; iが<= M; iは++ ){
         int型のオペアンプと、OP(読み取り)
        もし(OPの== 1 )を読み出す(ルート)。
        そう であれば(オペアンプ== 2 ){
           int型X、Y。
          LLのZ。
          読み取り(X)、(Y)を読み出す;(z)を読み取ります。
          (x、y、z)を修正します。            
        } 
        {
             int型のX;(x)を読み出します。
            もし(x ==ルート)のprintf(" %LLDする\ n "、MI [ 1 ])。
            // 整颗树
            他の 場合(ID [ルート]> ID [X] && ID [ルート<ID [X] +サイズ[X]){ // Xのサブツリーが変化
                INT POS =ルート、DELT = DEP [POS] -dep [X] - 。1 ;
                 のためのint型 P = 0 ; DELTと、DELT = >> 1、P ++)// 乗算
                 IF(&DELTを1。)POS = FA [POS] [P]; 
                のprintf(" %LLDの\のN- "、分(クエリ(11、N-、1、ID [POS] - 。1)、クエリ(11、N - 、ID [ POS] + サイズ[POS]、N-))); 
            } 
            のprintf(" %LLDの\のN- "、クエリ(。11、N - 、ID [X]、ID [X] +サイズ[X] - 1)); // 全く影響
        } 
    } 
}
コードの表示

おすすめ

転載: www.cnblogs.com/sto324/p/11246842.html