BZOJ_2631_tree_LCT

BZOJ_2631_tree_LCT

Description

 A tree with n points, the initial weight of each point is 1. There are q operations on this tree, and each operation is one of the following four operations:
+ uvc: add the natural number c to the weights of the points on the path from u to v;
- u1 v1 u2 v2: add the original value in the tree Some edges (u1, v1) are deleted, and a new edge (u2, v2) is added to ensure that it is still a tree after the operation;
* uvc: Multiply the weights of the points on the path from u to v by the natural number c ;
/uv: ask the weight sum of the points on the path from u to v, and find the remainder of the answer for 51061.

Input

  The first line contains two integers n, q
Next n-1 lines each contains two positive integers u, v, describing the tree
Next q lines, each describing an operation

Output

  Output one line for each/corresponding answer

Sample Input

3 2
1 2
2 3
* 1 3 4
/ 1 1

Sample Output

4

HINT

Data size and agreement

10% data guarantee, 1<=n, q<=2000

another 15% data guarantee, 1<=n, q<=5*10^4, no - operation, and the initial tree is a chain

Another 35% data guarantee, 1<=n, q<=5*10^4, no-operation

100% data guarantee, 1<=n, q<=10^5, 0<=c<=10^ 4


 LCT template questions. Pay attention to the order in which multiplication and addition are downloaded.

 

Code:

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 100050
#define mod 51061
#define ls ch[p][0]
#define rs ch[p][1]
#define get(x) (ch[f[x]][1]==x)
typedef unsigned int ui;
int n,m,ch[N][2],f[N],rev[N];
ui sum [N], mul [N], add [N], siz [N], val [N];
char opt[10];
inline bool isrt(int x) {
    return ch[f[x]][0]!=x&&ch[f[x]][1]!=x;
}
void pushdown(int p) {
    if(mul[p]!=1) {
        ui u = mul [p];
        sum [ls] = sum [ls] * u% mod; mul [ls] = mul [ls] * u% mod; add [ls] = add [ls] * u% mod; val [ls] = val [ls] * u% mod;
        sum[rs]=sum[rs]*u%mod; mul[rs]=mul[rs]*u%mod; add[rs]=add[rs]*u%mod; val[rs]=val[rs]*u%mod;
        mul [p] = 1;
    }
    if(add[p]) {
        ui d=add[p];
        sum [ls] = (sum [ls] + siz [ls] * d% mod)% mod; add [ls] = (add [ls] + d)% mod; val [ls] = (val [ls] + d)% mod;
        sum[rs]=(sum[rs]+siz[rs]*d%mod)%mod; add[rs]=(add[rs]+d)%mod; val[rs]=(val[rs]+d)%mod;
        add[p]=0;
    }
    if(rev[p]) {
        swap(ch[ls][0],ch[ls][1]);
        swap(ch[rs][0],ch[rs][1]);
        rev[ls]^=1; rev[rs]^=1;
        rev[p]=0;
    }
    /*cal(ls , add[p] , mul[p] , rev[p]);
    cal(rs , add[p] , mul[p] , rev[p]);
    add[p] = rev[p] = 0 , mul[p] = 1;*/
}
void pushup(int p) {
    you [p] = you [ls] + you [rs] +1;
    sum[p]=(sum[ls]+sum[rs]+val[p])%mod;
}
void update(int p) {
    if(!isrt(p)) update(f[p]);
    pushdown(p);
}
void rotate(int x) {
    int y=f[x],z=f[y],k=get(x);
    if(!isrt(y)) ch[z][ch[z][1]==y]=x;
    ch[y][k]=ch[x][!k]; f[ch[y][k]]=y;
    ch[x][!k]=y; f[y]=x; f[x]=z;
    pushup(y); pushup(x);
}
void splay(int x) {
    update(x);
    for(int fa;fa=f[x],!isrt(x);rotate(x))
        if(!isrt(fa))
            rotate(get(fa)==get(x)?fa:x);
}
void access(int p) {
    int t=0;
    while(p) splay(p),rs=t,pushup(p),t=p,p=f[p];
}
void makeroot (int p) {
    access(p); splay(p); swap(ls,rs); rev[p]^=1;
}
void link(int x,int p) {
    makeroot (x); f [x] = p;
}
void cut(int x,int p) {
    makeroot(x); access(p); splay(p); ls=f[x]=0;
}
void split(int x,int p) {
    makeroot(x); access(p); splay(p);
}
int main() {
    scanf("%d%d",&n,&m);
    int i,x,y,z,w;
    for(i=1;i<=n;i++) val[i]=mul[i]=siz[i]=sum[i]=1;
    for(i=1;i<n;i++) {
        scanf("%d%d",&x,&y); link(x,y);
    }
    for(i=1;i<=m;i++) {
        scanf("%s%d%d",opt,&x,&y);
        int p=y;
        if(opt[0]=='+') {
            scanf("%d",&z); split(x,p);
            sum[p]=(sum[p]+siz[p]*z%mod)%mod;
            val[p]=(val[p]+z)%mod;
            add[p]=(add[p]+z)%mod;
            //cal(p,z,1,0);
        }else if(opt[0]=='-') {
            scanf("%d%d",&z,&w); cut(x,y); link(z,w);
        }else if(opt[0]=='*') {
            scanf("%d",&z); split(x,p);
            sum[p]=sum[p]*z%mod;
            val[p]=val[p]*z%mod;
            add[p]=add[p]*z%mod;
            mul [p] = mul [p] * z% mod;
            //cal(p,0,z,0);
        }else {
            split(x,p); printf("%u\n",sum[p]);
        }
    }
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325085517&siteId=291194637