羅バレーP3833 [SHOI2012]マジックツリー(木スプリットチェーン)

トピックリンク:

https://www.luogu.com.cn/problem/P3833

アイデア:

ツリーボードセクションのタイトル

コード:

#include <ビット/ STDC ++ H>
 に#define LSノード<< 1、L、中間
 の#define RSノード<< 1 | 1、中間+ 1、R
 使用して 名前空間STDを、
const  int型 MAXN = 1E5 + 5 
typedefの長い 長いLL。
LLのn; 
int型のヘッド[MAXN]、TOT;
構造体ノード
{ 
    int型NXT、であり; 
} E [MAXN << 1 ]。
ボイド追加(int型のx、int型のY)
{ 
    E [TOT] .TO = Y、E [TOT] .nxt =頭部[X]、ヘッド[X] = TOT ++ 
} 
無効 add_edge(int型X、int型のY)
{ 
    (x、y)を追加し、追加(Y、X)。
} 
int型のDEP [MAXN]、F [MAXN]、SZ [MAXN]、息子[MAXN]。
ボイド DFS(INT U、INT FA)
{ 
    DEP [U] = DEP [FA] + 1 ; F [U] = FA; SZ [U] = 1 以下のためにINTは iはヘッド= [U]は;〜私は= E [I] .nxt)
    { 
        int型、V = E [I] .TOと、
        もし(!V = FA)
        { 
            DFS(V、U); 
            SZ [U] + = SZ [V]。
            もし(SZ [V]> SZ [息子[U]])
                息子[U] = V; 
        } 
    } 
} 
int型のID [MAXN]、トップ[MAXN]、CNT。
ボイド DFS2(INT U、INT T)
{ 
    トップ[U] = T; ID [U] = ++ CNT。
    もし(息子[U])
        DFS2(息子[U]、T); 
    以下のためにINTは iはヘッド= [U]は;〜私は= E [I] .nxt)
    { 
        int型、V = E [I] .TOと、
        もし(!!V = F [U] && V = 息子[U])
            DFS2(V、V); 
    } 
} 
LLツリー[MAXN << 2 ]、怠惰[MAXN << 2 ]。
ボイド push_up(int型ノード)
{ 
    ツリー[ノード] =ツリー[ノード<< 1 ] +ツリー[ノード<< 1 | 1 ]。
} 
ボイドビルド(int型ノード、INT L、INT R)
{ 
    場合(L == R)のリターン;
    INTの半ば=(L + R)>> 1 
    ビルド(LS);ビルド(RS); 
    push_up(ノード)。
} 
ボイド push_down(int型ノード、INT L、INT R、INT MID)
{ 
    場合(怠惰[ノード])
    {
        ツリー[ノード << 1 ] + =(MID-L + 1)* 怠惰[ノード]。
        ツリー[ノード << 1 | 1 ] + =(R-MID)* 怠惰[ノード]。
        怠惰[ノード << 1 ] + = 怠惰[ノード]。
        怠惰な[ノード << 1 | 1 ] + = 怠惰[ノード]。
        怠惰[ノード] = 0 ; 
    } 
} 
ボイド更新(int型ノード、INT L、INT R、int型のx、int型のy、int型k)を
{
    場合ツリー[ノード]。(L> = X && R <= Y)
    { 
        ツリー[ノード] + =(R-L + 1)* K;怠惰[ノード] + = K。リターン; 
    } 
    int型のミッド=(L + R)>> 1 
    push_down(ノード、L、R、MID)。
    もし(x <= MID)
        更新(LS、X、Y、K)。
    もし(Y> MID)
        更新(RS、X、Y、K)。
    push_up(ノード)。
} 
LLクエリ(INTノード、INT L、INT R、int型のx、int型Y)
{ 
    場合(L> = X && R <= y)を返し
    LL ANS = 0 INTの半ば=(L + R)>> 1 
    push_down(ノード、L、R、MID)。
    もし(x <= MID)
        ANS + = クエリ(LS、X、Y)
    もし(Y> MID)
        ANS + = クエリ(RS、X、Y)
    戻り値は、ANS; 
} 
ボイド tree_update(int型のx、int型のy、int型Z)
{ 
    int型の FX = TOP [X]、FY = TOP [Y]。
    一方、(!FX = FY)
    { 
        場合(DEP [FX] < DEP [FY])スワップ(x、y)は、スワップ(FX、FY)。 
        更新(11 、CNT、ID [FX]、ID [x]は、Z)。
        X = F [FX]、FX = TOP [X]。
    } 
    もし(ID [X]> ID [Y])スワップ(X、Y)
    アップデート(11 、CNT、ID [x]は、ID [Y]、Z); 
} 
int型のmain()
{ 
    scanf関数(" %のLLD "、&N)
    memsetの(頭、 - 1はsizeof (ヘッド))。
    以下のためにINT iが= 1 ; N I <; I ++ 
    { 
        LL X、Y; scanf関数(" %LLD%LLD "、およびX& 0 Y)。
        add_edge(X、Y)
    } 
    DFS( 0); DFS2(00 ); 
    ビルド(11 、N)
    INT Q; scanf関数(" %のD "、&Q)。
    一方、(q-- 
    { 
        チャー STR [ 2 ]。
        scanf関数(" %S " 、STR)。
        もし(STR [ 0 ] == ' A ' 
        { 
            LL X、Y、Z; scanf関数(" %LLD%LLD%LLD "、およびX&Y、およびZ); tree_update(X、Y、Z)。
        }
        
        { 
            LL X; scanf関数(" %のLLD "、およびX);のprintf(" %のLLD \ n "、クエリ(11、nは、ID [x]は、ID [X] + SZ [X] - 1 )) ; 
        } 
    } 
    戻り 0 
}

 

おすすめ

転載: www.cnblogs.com/ljxdtc666/p/12594329.html