Tree chain split memories notes

Tree chain split memories notes

Excerpt definition:

  1. Heavy sons: the number of all sons of neutrons tree nodes father node up (size maximum) nodes;
  2. Light son: father node in addition to heavy son's son;
  3. Multiple edges: father, son nodes and re-connected into the edge;
  4. Light Edge: Father son nodes and light even into the edge;
  5. Heavy chain: the path formed by connecting a plurality of multiple edges;
  6. Light chain: a path formed by connecting a plurality of light sides;

Then there is no then the

All the stuff about "light" words are futile

A bit better understanding of the drawing,

The red dots mark the starting point of a heavy chain

We found that the heavy side edges are No. 1,2,3,4,8,10,11

More importantly, all nodes in a heavy chain (also considered a node)

dfs sequence in the tree defining the chain split is also a little different

Because in order to facilitate maintenance, we DFS order nodes on a continuous chain

Chain famous tree split in two dfs dfs pretreatment sequence, depth and severity of his son, light and heavy chains, the size of the subtrees

The main idea of ​​the tree and then split the chain is on the heavy maintenance of a variety of advanced data structures, for example segment tree, balanced tree ......

Okay, so

Board problem Code:

#include <bits / STDC ++ H.>
 the using  namespace STD;
 const  int N = 200005 ;
 long  long n-, m, R & lt, P; // number of nodes of the tree, the number of operations, and the root number modulo the number of 
long  Long Val [N]; // initial weights of each node 
Long  Long CNT = 0 , HED [N], TAL [N * 2 ], NXT [N * 2 ];
 Long  Long F [N]; // father node 
Long  Long D [N]; // node depth 
Long  Long size [N]; // subtree node number 
Long  Long S [N] = {0 }; // weight son ID 
Long  Long ID [N]; // the DFS sequence 
Long  Long Rk [N]; // number of the corresponding sequence in the original dfs tree 
Long  Long T [N]; // chain top 
Long  Long = TOT 0 ; // timestamp   
struct ST {
     Long  Long value;
     Long  Long LZT; 
} T [N << 2 ]; // segment tree 
void addege ( Long  Long A, Long  Long B) { 
    CNT++;
    tal[cnt]=b;
    nxt[cnt]=hed[a];
    hed[a]=cnt; 
}
void dfs1(long long u,long long fa,long long dis){//第一遍dfs 
    d[u]=dis;//节点初始化 
    f[u]=fa;
    size[u]=1;
    for(long long i=hed[u];i;i=nxt[i]){
        long long v=tal[i];
        if(v==fa) Continue ; 
        DFS1 (V, U, DIS + . 1 ); // iterate son 
        size [U] + = size [V]; // update the number of sub-tree nodes 
        IF (S [U] == 0 ) S [U] = V;
         the else  IF (size [S [U]] <size [V]) S [U] = V; // select weight son 
    } 
} 
void DFS2 ( Long  Long U, Long  Long GF) { // current node, chain top 
     T [U] = GF; 
    ID [U] = ++ TOT; 
    Rk [TOT] = U;
     IF (! S [U]) return ;
    dfs2(s[u],gf);
    for(long long i=hed[u];i;i=nxt[i]){
        long long v=tal[i];
        if(v==f[u]) continue;
        if(v==s[u]) continue;
        dfs2(v,v);  
    } 
}
long long len(long long l,long long r){return r-l+1;}
void push_up(long long num){
    t[num].value=(t[num<<1].value+t[num<<1|1].value)%p;
}
void push_down(long long l,long long r,long long num){
    if(t[num].LZT){
        long long mid=(l+r)>>1;
        t[num<<1].LZT+=t[num].LZT;
        t[num<<1|1].LZT+=t[num].LZT;
        t[num<<1].value+=len(l,mid)*t[num].LZT;
        t[num<<1].value%=p;
        t[num<<1|1].value+=len(mid+1,r)*t[num].LZT;
        t[num<<1|1].value%=p;
        t[num].LZT=0;
    }
} 
void build(long long l,long long r,long long num){
    if(l==r){
        t[num].LZT=0;
        t[num].value=val[Rk[l]]%p;
        return;
    }
    long long mid=(l+r)>>1;
    build(l,mid,num<<1),build(mid+1,r,num<<1|1);
    push_up(num);
}
void upt(long long l,long long r,long long num,long long L,long long R,long long X){
    if(l>=L&&r<=R){
        t[num].LZT+=X;
        t[num].LZT%=p; 
        t[num].value+=len(l,r)*X;
        t[num].value%=p; 
        return;
    }
    if(l>R||r<L) return;
    long long mid=(l+r)>>1;
    push_down(l,r,num);
    upt(l,mid,num<<1,L,R,X);
    upt(mid+1,r,num<<1|1,L,R,X);
    push_up(num);
}
long long qus(long long l,long long r,long long num,long long L,long long R){
    if(l>=L&&r<=R){
        return t[num].value%p;
    }
    if(l>R||r<L) return 0;
    long long mid=(l+r)>>1;
    push_down(l,r,num);
    return (qus(l,mid,num<<1,L,R)+qus(mid+1,r,num<<1|1,L,R))%p;
}
long long ask(long long x,long long y){
    long long sum=0;
    while(T[x]!=T[y]){
        if(d[T[x]]<d[T[y]]) swap(x,y);
        sum+=qus(1,n,1,id[T[x]],id[x]);
        sum%=p;
        x=f[T[x]];
    } 
    if(d[x]>d[y]) swap(x,y);
    return (sum+qus(1,n,1,id[x],id[y]))%p;
} 
void pus(long long x,long long y,long long z){
    while(T[x]!=T[y]){
        if(d[T[x]]<d[T[y]]) swap(x,y);
        upt(1,n,1,id[T[x]],id[x],z);
        x=f[T[x]];
    } 
    if(d[x]>d[y]) swap(x,y);
    upt(1,n,1,id[x],id[y],z);
} 
int main(){
    scanf("%lld%lld%lld%lld",&n,&m,&r,&p);
    for(long long i=1;i<=n;i++){
        scanf(" % LLD " , & Val [I]); 
    } 
    for ( Long  Long I = . 1 ; I <n-; I ++ ) {
         Long  Long A, B; 
        Scanf ( " % LLD% LLD " , & A, & B); 
        addege (a, B); 
        addege (B, a); 
    } 
    DFS1 (R & lt, - . 1 , . 1 ); // starting from the root, the depth of each node is determined, the number of sub-tree nodes, father, son number and weight
     / / // node, a parent node, the depth 
    DFS2 (R & lt, R & lt); // second pass to obtain remaining information dfs 
     @-------------------------------------------------- ------------------------
     // Next, enter the segment tree section! 
    Build ( . 1 , n-, . 1 ); // achievements of   
    the while (M-- ) {
         Long  Long opt; 
        Scanf ( " % LLD " , & opt);
         IF (== opt . 1 ) {
             Long  Long X, Y, Z; 
            Scanf ( " %% LLD LLD LLD% " , & X, & Y, & Z); 
            Z % = P; 
            PUS (X, Y, Z); 
        } 
        the else if(opt==2){
            long long x,y;
            scanf("%lld%lld",&x,&y);
            printf("%lld\n",ask(x,y)%p);
        }
        else if(opt==3){
            long long x,y;
            scanf("%lld%lld",&x,&y);
            y%=p;
            upt(1,n,1,id[x],id[x]+size[x]-1,y);
        }
        else{
            long long x;
            scanf("%lld",&x);
            printf("%lld\n",qus(1,n,1,id[x],id[x]+size[x]-1)%p);
        }
    }
    return 0;
} 

 

Guess you like

Origin www.cnblogs.com/QYJ060604/p/11620624.html