[SHOI2012]魔法の木

トピックポータル

地方選挙D2T3テストボードそれは本当にまれです。~~~

この問題は、各クエリ操作ごとに、uからvへのパスを維持するために、操作を追加し、Uにサブツリーのルートを依頼するための裸の鎖分割ツリーです。チェーンは、私が見ることができる木分割されない場合は、期間のブログへの、コード内の細部を詳細に行くことはありません-

リファレンスコードは以下のとおりであります:

#include <iostreamの> 
する#include <cstdioを> 
の#define N 400005 
の#define M 800005 
の#define LC K * 2 
の#defineのRC K * 2 + 1台
の#define半ば(L + R)/ 2 
長の長いの#define INT 
名前空間stdを使用して; 
構造体ノード
{ 
    int型のL、R、W、タグ。
}ツリー[4 *のN]。
N INT、M、R、P、X、Y、Z。
int型V [M]、ヘッド[M]、NXT [M]、CNT。
INT DEP [N]、FA [N]、息子[N]、サイズ[N]、トップ[N]、SEG [N]、ID。
文字Q; 
読み取りINT()
{ 
    int型のx = 0、F = 1; CHAR CH = GETCHAR()。
    一方、(CH < '0' || CH> '9'){IF(CH == ' - ')は、f = -1; CH = GETCHAR();} 
    一方(CH> = '0' && CH <= '9 「){X = X * 10 + CH-48、CH = GETCHAR();} 
    戻りのx * Fを、
    V [++ CNT]はBを=。
    NXT [CNT] =ヘッド[A]。
    [A] = CNTヘッド。
} 
ボイドDFS1(INTノード、父INT)
{ 
    DEP [ノード] = DEP [父] +1。
    FA [ノード] =父。
    サイズ[ノード] = 1。
    int型maxson = -1; 
    用(INT I =ヘッド[ノード]; I; I = NXT [I])
    { 
        int型行く= Vの[I]。
        (==父親を行く)続行。
        DFS1(行く、ノード)。
        サイズ[ノード] + =サイズ[移動]。
        IF(サイズ[移動]> maxson)maxson =サイズ、[移動]息子[ノード] =行きます。
    } 
} 
ボイドDFS2(INTノード、int型topfather)
{ 
    SEG [ノード] = ++ ID。
    トップ[ノード] = topfather。
    (!息子[ノード])であればリターン。
    DFS2(息子[ノード]、topfather)。
    用(INT I =ヘッド[ノード]; I; I = NXT [I])
    { 
        int型行く= Vの[I]。
        場合(行く== FA行く|| [ノード] ==息子[ノード])続けます。
        DFS2(行く、行きます)。
    } 
} 
ボイドビルド(int型L、int型のR、int型K)
{ 
    ツリー[K] .L = L;ツリー[K] .R = R。
    (L == R)戻った場合。
    (リットル、ミッド、LC)を構築します。
    (ミッド+ 1、R、RC)を構築します。
} 
ボイドプッシュダウン(int型K)
{ 
    ツリー[LC] .TAG + =ツリー[K] .TAG。
    ツリー[RC] .TAG + =ツリー[K] .TAG。
    ツリー[LC] .W + =(ツリー[LC] .Rツリー[LC] .L + 1)*ツリー[K] .TAG。
    ツリー[RC] .W + =(ツリー[RC] .Rツリー[RC] .L + 1)*ツリー[K] .TAG。
    ツリー[K] .TAG = 0。
    返します。
} 
ボイド押し上げ(int型K)
{ 
    ツリー[K] .W =ツリー[LC] .W +ツリー[RC] .W。
    返します。
} 
ボイド追加(int型のx、int型のY、int型K)
{ 
    int型L =ツリー[K] .L、R =ツリー[K] .R。
    IF(L> = X && R <= Y)
    { 
        ツリー[K] .TAG + = Z。
        ツリー[K] .W + =(R-L + 1)* Z。
        返します。
    } 
    IF(ツリー[K] .TAG)プッシュダウン(K)。
    IF(X <= MID)(X、Y、LC)を追加します。
    (Y>中間)が追加した場合(X、Y、RC)。
    突き上げ(K)。
} 
int型の照会(int型のx、int型のY、int型K)
{ 
    int型L =ツリー[K] .L、R =ツリー[K] .R。
    IF(L> = X && R <= Y)
    { 
        戻りツリー[K] .W。
    } 
    IF(ツリー[K] .TAG)プッシュダウン(K)。
    int型のres = 0; 
    (X <= MID)RES + =クエリ(X、Y、LC)であれば、
    もし(Y> MID)RES + =クエリ(X、Y、RC)。
    解像度を返します。
}
Taddでは(int型のx、int型のy)を無効
{ 
    一方(上面[X] = TOP [Y]!)
    { 
        IF(DEP [TOP [X] <DEP [トップ[Y])スワップ(X、Y)
        追加(SEG [TOP [X]、SEG [x]は、1)。
        X = FA [TOP [X]]。
    } 
    IF(DEP [X]> DEP [Y])スワップ(X、Y)
    追加(SEG [x]は、SEG [Y]、1)。
} 
INT Treequery(INT X)
{ 
    戻りクエリ(SEG [x]は、SEG [X] +サイズ[X] -1,1)。
} 
)(主符号付き
{ 
    N =読み取ります()。
    以下のために(; iがn <I ++はI = 1 INT)
    { 
        X =リード(); Yは、読み取り=(); 
        X ++; Y ++。
        (x、y)を追加し、(x、y)を加えます。
    } 
    DFS1(1,0); DFS2(1,1)。
    (1、nは、1)を構築します。
    M =読み取ります(); 
    一方、(M--)
    {
        cinを>> Q; 
        IF(Q == 'A')
        { 
            X =リード(); Yは()を読み取る。=; Zは読み取り=(); 
            X ++; Y ++。
            TADD(X、Y)
        } 
        { 
            X =リード()。
            X ++; 
            COUT << Treequery(X)<< ENDL。
        } 
    } 
}

  

おすすめ

転載: www.cnblogs.com/szmssf/p/11145035.html