P3833 [SHOI2012]マジックツリー(木分割チェーンテンプレートのタイトル)

トピックへのリンク:https://www.luogu.org/problem/P3833

タイトル効果は:を含むツリーは、各ノードが最初に0は、次の2回の操作で、N個のノードを有します。

1.AddのUVDは、UとVとの間の経路上の全てのノードの値を表すプラスDです。

2.Query uがuは、サブツリー、どのように多くの合計のフルーツを根ざしポイントに、現在の果樹を表し?

 

ソリューションの概要:連鎖スプリット木板、特にコードのコメントを参照するには

コード:

#include <ビット/ STDC ++ H.>
 使用して 名前空間STD; 
typedefの長い ロング; LL
 のconst  int型 MAXN = 100005 ;
 int型のTOT、CNT、ヘッド【MAXN]は、N-、M、V [MAXN]; 
LLツリー[MAXN * 4 ] 、怠惰な[* MAXN 4。];
 int型のD [MAXN]、サイズ[MAXN]、息子[MAXN]、ID [MAXN]、RK [MAXN]、FA [MAXN]、トップ[MAXN];
 // サイズ[I]サブツリーのノードの番号i、トップ[i]はiは、重鎖の上面であり、息子[i]はiが重い息子の数である
 // D [i]は、ノードの真の深さは、Iであり、ID [i]はiは新しい番号、FA [i]は番号iの父親である
構造体のエッジ{
     int型、V、次に
エッジ} [MAXN << 1。];
 無効(ADDをINT U、int型V){ 
    エッジ[TOT] .V = V、
    エッジ[TOT] .next = 頭部[U]; 
    頭部[U] = TOT ++ ; 
} 
ボイド DFS1(INT U、INT PRE){ // 最初のDFSは、各ノード、親ノード、サブツリーの大きさの深さにわたって求めて 
    D [U] = D [事前] + 。1 ; 
    FA [U] = 予備; 
    サイズ[U] = 1 ;
     のためのint型 I =頭[U ] ;! = I - 1 ; I = エッジ[I] .next){
         int型 V = エッジ[I] .V;
         IF(V =! PRE){
            DFS1(V、U); 
            サイズ[U] + = サイズ[V];
             IF(サイズ[ソン[U] <サイズ[V])の息子[U] = V; 
        } 
    } 
} 
ボイド DFS2(INT U、INT TP){ // 重鎖の各新しいノード番号と重量を見つける場所トップと息子 
    トップ[U] = TP、ID [U] = CNT ++、RK [CNT] = U;
     IF (息子[U])DFS2 (息子[U]、TP); 
     // 重鎖への連続的な重鎖上の全てのノードは、セグメントツリー情報によって維持され得ることを確実にするため、DFS開始及び再子ノード
    のためにint型 I =ヘッド[U];私は!= - 1 ; I = エッジ[I] .next){
         int型 V = エッジ[I] .V;
         IF(V FA = [U] = V &&!息子[U])DFS2(V、V)。
    } 
} 
ボイド押し上げ(int型RT){ 
    ツリー[RT] =ツリー[RT << 1 ] +ツリー[RT << 1 | 1 ]。
} 
ボイドプッシュダウン(int型 L、int型の R、int型RT){
     場合(怠惰[RT]){ 
        ツリー[RT << 1 ] =ツリー[RT << 1 ] +怠惰[RT] * L。
        ツリー[RT << 1 | 1 ] =木[RT << 1 | 1 ] +怠惰[RT] * R。
        怠惰な[RT <<1 ] + = 怠惰[RT]。
        怠惰な[RT << 1 | 1 ] + = 怠惰[RT]。
        怠惰[RT] = 0 ; 
    } 
} 
ボイドビルド(int型 L、int型の R、int型RT){ 
    怠惰[RT] = 0 ;
    もし(L == R){ 
        ツリー[RT] = V [RK [L]]。
        返します
    } 
    INT半ば= L + R >> 1 
    構築(リットル、ミッド、RT << 1 )。
    (半ばを構築 +1、R、RT << 1 | 1 ); 
    突き上げ(RT)。
} 
ボイド更新(int型 L、INT R、int型のVal、INT L、INT R、INT RT){
     場合(L <= 1 && R> = R){ 
        ツリー[RT] + = 1LL *(R-L + 1 *)のVal ; 
        怠惰[RT] + = ヴァル。
        返します
    } 
    INT半ば= L + R >> 1 
    プッシュダウン(MID -l + 1、R- 半ば、RT)。
    もし(MID> = L)更新(L、R、ヴァル、L、中間、RT << 1 )。
    もし(MID <R)更新(L、R、ヴァル、中間+ 1、R、RT << 1 | 1 )。
    突き上げ(RT)。
} 
LLクエリ(int型 L、INT R、int型の L、INT R、INT RT){
     場合(L <= 1 && R> = R)戻りツリー[RT]。
    INT半ば= L + R >> 1LLのRES = 0 
    プッシュダウン(MID -l + 1、R- 半ば、RT)。
    もし(MID> = L)RES + =クエリ(L、R、L、中間、RT << 1 )。
    IF(MID <R&LT)RES + =クエリ(L、R&LT、MID + 。1、R&LT、RT << 1 | 1 );
     戻り、RESを
} 
ボイド更新(int型のx、int型の yは、int型 {ヴァル)を// yにXを変更します最短経路の値
    一方(TOP [X]!= TOP [Y]){ // 最大ジャンプしない同一の重鎖
        IF(D [TOP [X] < D [TOP [Y])スワップ(X、 Y)、
        更新(ID [TOP [X]、ID [X]、ヴァル、1、N-、1。); 
        X = FA [TOP [X]]; // 親ノードの重鎖の上部へのジャンプ
    }
     IF(ID [X]> ID [Y])スワップ(X、Y); //二つの同一の重鎖内のノードが、同じノードではないかもしれない 
    更新(ID [X]、ID [Y]、ヴァル、1、N - 、1 ); 
} 
ASK 11(int型の Xを、int型 Y){ // クエリX Yの最短パス値 
    LL RES = 0 ;
     ながら(!TOP [X] = TOP [Y]){
         IF(D [TOP [X] < D [TOP [Y])スワップ(x、y)は; 
        RES + =クエリ(ID [TOP [X]、ID [X]、1、N-、1。); 
        X = FA [TOP [X]]; 
    } 
    IF(ID [X]> ID [Y])スワップ(X、Y); 
    RES + =クエリ(ID [X]、ID [Y]、1、N-、1。);
    リターンのres; 
} 
int型のmain(){ 
    scanf関数(" %のD "、&N)
    memsetの(頭、 - 1はsizeof (ヘッド))。
    以下のためにint型 i = 1 ; iがn <; iは++ ){
         int型Uを、V。
        scanf関数(" %d個の%d個"、&​​U&V); 
        U ++; V ++ ; 
        (V、U)を追加します。
    } 
    のscanf(" %dの"、&M)。
    CNT = 0、TOT =0 ; 
    DFS1(10)、DFS2(11 )。
    (ビルド1、nは、1 )。
    一方、(M-- ){
         チャー OP [ 10 ]。
        int型のL、R、RT、ヴァル。
        scanf関数(" %sの" 、OP)。
        もし(OP [ 0 ] == ' A ' ){ 
            scanf関数(" %D%D%D "、&​​L&R&ヴァル)。
            L ++; R ++ ; 
            更新(L、R、ヴァル)。 
        } { 
            scanfの(" %のD "、&​​RT); RT ++ ; 
            のprintf(" %LLDの\のN- "、クエリ(ID [RT]、ID [RT] +サイズ[RT] - 。11、N - 、1 ));
             // サブツリーのサイズがサイズであるので、[RT]、出発点は、IDの数であり、[RT]をIDから[RT] IDに[RT] +サイズ[RT ] - 1 
        } 
    } 
    戻り 0 ; 
}

 

おすすめ

転載: www.cnblogs.com/zjl192628928/p/11298733.html