Chain split tree (tree sectional)

Cancer thing ... but a league actually gone out over the years about the three tree cross ... Oh ~

question type

As the name suggests what belongs to graph theory. Based on the data structures: segment tree

Operation 1: Format: 1 shows a tree XYZ values ​​of all the nodes on the shortest path from the node x to y plus z are

Operation 2: Format: 2 XY indicates finding a tree node from x to y value on the shortest path, and all nodes

Operation 3: Format: 3 x will be represented by an xz all nodes within the subtree root values ​​are plus z

Operation 4: Format: 4 x values ​​represent all nodes within the subtree root node seeking and at x

Principle of the method

... I feel that I have to describe has nothing to say, as I think the best moved the blog to understand it.

Luo Valley Daily: Tree chain split

Pre-knowledge should be added to a LCA, but a tree difference seems less useful.

Said very clearly, but at least for me, konjac, and his board code that does make people very uncomfortable

So here we attach a link to its board title Code (excerpt from zengqinyi from luogu)

Board questions

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#define Rint register int
#define mem(a,b) memset(a,(b),sizeof(a))
#define Temp template<typename T>
using namespace std;
typedef long long LL;
Temp inline void read(T &x){
    x=0;T w=1,ch=getchar();
    while(!isdigit(ch)&&ch!='-')ch=getchar();
    if(ch=='-')w=-1,ch=getchar();
    while(isdigit(ch))x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar();
    x=x*w;
}

#define mid ((l+r)>>1)
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define len (r-l+1)

const int maxn=200000+10;
int n,m,r,mod;
//见题意 
intE, BEG [MAXN], NEX [MAXN], to [MAXN], W [MAXN], wt [MAXN];
 // front chain to star array, w [], wt [] array start point right 
int A [ << MAXN 2 ], Laz [MAXN << 2 ];
 // segment tree array, lazy operation 
int Son [MAXN], ID [MAXN], FA [MAXN], CNT, DEP [MAXN], SIZ [MAXN], top [MAXN]; 
 // son [] weight son number, id [] a new number, fa [] parent node, cnt dfs_clock / dfs sequence, dep [] depth, siz [] subtree size, top [] current top strand node 
int RES = 0 ;
 // query answer 

inline void the add ( int X, int Y) { // before the star plus side chain 
    to [E ++] = Y; 
    NEX [E] = BEG [X]; 
    BEG [ X] =e;
}
//-------------------------------------- 以下为线段树 
inline void pushdown(int rt,int lenn){
    laz[rt<<1]+=laz[rt];
    laz[rt<<1|1]+=laz[rt];
    a[rt<<1]+=laz[rt]*(lenn-(lenn>>1));
    a[rt<<1|1]+=laz[rt]*(lenn>>1);
    a[rt<<1]%=mod;
    a[rt<<1|1]%=mod;
    laz[rt]=0;
}

inline void build(int rt,int l,int r){
    if(l==r){
        a[rt]=wt[l];
        if(a[rt]>mod)a[rt]%=mod;
        return;
    }
    build(lson);
    build(rson);
    a[rt]=(a[rt<<1]+a[rt<<1|1])%mod;
}

inline void query(int rt,int l,int r,int L,int R){
    if(L<=l&&r<=R){res+=a[rt];res%=mod;return;}
    else{
        if(laz[rt])pushdown(rt,len);
        if(L<=mid)query(lson,L,R);
        if(R>mid)query(rson,L,R);
    }
}

inline void update(int rt,int l,int r,int L,int R,int k){
    if(L<=l&&r<=R){
        laz[rt]+=k;
        a[rt]+=k*len;
    }
    else{
        if(laz[rt])pushdown(rt,len);
        if(L<=mid)update(lson,L,R,k);
        if(R>mid)update(rson,L,R,k);
        a[rt]=(a[rt<<1]+a[rt<<1|1])%mod;
    }
}
//---------------------------------以上为线段树 
inline int qRange(int x,int y){
    int ans=0;
    while(top[x]!=top[y]){// When two points not on the same strand 
        IF (DEP [Top [x]] <DEP [Top [Y]]) the swap (x, Y); // the point x where the top of the chain to a depth deeper the point 
        RES = 0 ; 
        Query ( . 1 , . 1 , n-, ID [top [x]], ID [x]); // ANS plus x to the point x where the chain to the top section of this section and the right point 
        ANS + = RES ; 
        ANS % = MOD; // press that Italy modulo 
        x = FA [top [x]]; // the x jump point above that of the top strand where a point x 
    }
     // until the two points in the chain the 
    IF (DEP [x]> DEP [Y]) the swap (x, Y); // the point x of the point deeper 
    RES = 0 ; 
    Query ( . 1 , . 1, n-, ID [X], ID [Y]); // time interval plus the two points at this time and to 
    ANS + = RES;
     return ANS% MOD; 
} 

inline void updRange ( int X, int Y , int K) { // supra 
    K% = MOD;
     the while ! (Top [X] = Top [Y]) {
         IF (DEP [Top [X]] < DEP [Top [Y]]) the swap (X, Y ); 
        Update ( . 1 , . 1 , n-, ID [Top [X]], ID [X], K); 
        X = FA [Top [X]]; 
    } 
    IF (DEP [X]> DEP [Y]) the swap (X, Y); 
    Update ( . 1, . 1 , n-, ID [X], ID [Y], K); 
} 

inline int qSon ( int X) { 
    RES = 0 ; 
    Query ( . 1 , . 1 , n-, ID [X], ID [X] + SIZ [X] - . 1 ); // subtree is the right end section ID [X] + SIZ [X] -1 
    return RES; 
} 

inline void updSon ( int X, int K) { // supra 
    Update ( . 1 , . 1 , n-, ID [X], ID [X] + SIZ [X] - . 1 , K); 
} 

inline void DFS1 ( int X,int F, int Deep) { // X current node, f father, deep depth of 
    DEP [X] = Deep; // tag for each depth point 
    FA [X] = F; // tag fathers each point 
    SIZ [ X] = . 1 ; // tag for each non-leaf nodes of the subtree size 
    int Maxson = - . 1 ; // record the number of son son weight 
    for (I Rint = BEG [X]; I; I = NEX [I]) {
         int Y = to [I];
         IF (Y == F) Continue ; // if the father Continue 
        DFS1 (Y, X, Deep + . 1 ); // DFS his son 
        siz [x] + = siz [ y] ; //The number applied to its body it son 
        IF (SIZ [Y]> Maxson) Son [X] = Y, Maxson = SIZ [Y]; // tag weight of each non-leaf nodes son ID 
    } 
} 

inline void DFS2 ( int X, int Topf) { // X current node, the currently topmost Topf chain node 
    ID [X] = CNT ++; // tag for each point, the new numbering 
    wt [CNT] = W [X]; / / the initial value of each point is assigned numbers up to the new 
    top [X] = Topf; // the top of the point where the chain 
    IF (son [X]!) return ; // if no son returns 
    dfs2 (son [x ], Topf); // by weight of the first son process, then the processing sequence of the light son recursive process 
    for (I Rint = BEG [X]; I; I = NEX [I]) {
         int Y =to [I];
         IF (FA == Y [X] || Y == Son [X]) Continue ; 
        DFS2 (Y, Y); // for each son has a light chain from the beginning of its own 
    } 
} 

int main () { 
    Read (n-); Read (m); Read (R & lt); Read (MOD); 
    for (Rint I = . 1 ; I <= n-; I ++ ) Read (W [I]);
     for ( RINT I = . 1 ; I <n-; I ++ ) {
         int A, B; 
        Read (A); Read (B); 
        the Add (A, B); the Add (B, A); 
    } 
    DFS1 (R & lt, 0 , . 1 ) ; 
    DFS2 (R & lt, R & lt); 
    Build ( . 1 , . 1 , n-);
    while(m--){
        int k,x,y,z;
        read(k);
        if(k==1){
            read(x);read(y);read(z);
            updRange(x,y,z);
        }
        else if(k==2){
            read(x);read(y);
            printf("%d\n",qRange(x,y));
        }
        else if(k==3){
            read(x);read(y);
            updSon(x,y);
        }
        else{
            read(x);
            printf("%d\n",qSon(x));
        }
    }
}

Step analysis

Such a long thing, you say to backplane daughter I really do not believe.

I still understand what steps to remember.

1. recorded using dfs subtree size, the parent node array, and the array select depth weight son

2. Mark Dfs each point sequence, and mark the node sequence corresponding to Sequence Dfs. (A pair of mutually mapped). Recording start end of each heavy chain. When making dfs order, first traversal heavy son, in order to ensure continuous heavy chain sequence Dfs. Then go light chain

3. For

All tree nodes from x to y shortest path node values ​​plus z

Tree request from x to y values ​​of all nodes in the shortest path of nodes and

That is associated with the shortest path operations, we are not in a situation need to put on a chain disposed of, then when do the same chain of intervals and.

4. For

X is a root node will be the subtree nodes values ​​are all plus z

Find all the nodes in the value x is a root node of the subtree and

This sub tree-related operations, because our numbers are continuous dfs directly modify the interval (incoming dfs order) range query.

 

Guess you like

Origin www.cnblogs.com/Uninstalllingyi/p/11826294.html