2631: tree LCT

来源:互联网 发布:java怎么运行程序 编辑:程序博客网 时间:2024/04/29 12:06

傻逼题无脑码了20几分钟就码完啦= =
结果顺手把y打成了x就WA了一发。。。
unsigned int 比 long long快很多啊

#include<iostream>#include<cstdio>#define ll unsigned int#define P 51061#define N 100005using namespace std;int n,Q;int rev[N],size[N],stack[N],fa[N],tree[N][2];ll val[N],sum[N],tag_mul[N],tag_add[N];inline int read(){    int a=0,f=1; char c=getchar();    while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}    while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}    return a*f;}inline bool isroot(int k){    return tree[fa[k]][0]!=k&&tree[fa[k]][1]!=k;}inline void pushup(int k){    size[k]=size[tree[k][0]]+size[tree[k][1]]+1;    sum[k]=(sum[tree[k][0]]+sum[tree[k][1]]+val[k])%P;}inline void pushdown(int k){    if (rev[k])    {        rev[k]^=1; rev[tree[k][0]]^=1; rev[tree[k][1]]^=1;        swap(tree[k][0],tree[k][1]);    }    if (tag_mul[k]==1&&tag_add[k]==0) return;    val[tree[k][0]]=(val[tree[k][0]]*tag_mul[k]+tag_add[k])%P;    sum[tree[k][0]]=(sum[tree[k][0]]*tag_mul[k]+tag_add[k]*size[tree[k][0]])%P;    tag_mul[tree[k][0]]=(tag_mul[k]*tag_mul[tree[k][0]])%P;    tag_add[tree[k][0]]=(tag_mul[k]*tag_add[tree[k][0]]+tag_add[k])%P;    val[tree[k][1]]=(val[tree[k][1]]*tag_mul[k]+tag_add[k])%P;    sum[tree[k][1]]=(sum[tree[k][1]]*tag_mul[k]+tag_add[k]*size[tree[k][1]])%P;    tag_mul[tree[k][1]]=(tag_mul[k]*tag_mul[tree[k][1]])%P;    tag_add[tree[k][1]]=(tag_mul[k]*tag_add[tree[k][1]]+tag_add[k])%P;    tag_mul[k]=1; tag_add[k]=0;}inline void rotate(int x){    int y=fa[x],z=fa[y],l=tree[y][1]==x,r=l^1;    if (!isroot(y)) tree[z][tree[z][1]==y]=x;    fa[x]=z; fa[y]=x; fa[tree[x][r]]=y;    tree[y][l]=tree[x][r]; tree[x][r]=y;    pushup(y); pushup(x);}inline void splay(int x){    int top=0;    stack[++top]=x;    for (int i=x;!isroot(i);i=fa[i]) stack[++top]=fa[i];    for (int i=top;i;i--) pushdown(stack[i]);    while (!isroot(x))    {        int y=fa[x],z=fa[y];        if (!isroot(y))        {            if (tree[y][0]==x^tree[z][0]==y) rotate(x); else rotate(y);        }        rotate(x);    }}inline void access(int x){    for (int t=0;x;t=x,x=fa[x])        splay(x),tree[x][1]=t,pushup(x);}inline void rever(int x){    access(x); splay(x); rev[x]^=1;}inline void link(int x,int y){    rever(x); fa[x]=y;}inline void cut(int x,int y){    rever(x); access(y); splay(y);    tree[y][0]=fa[x]=0; pushup(y);}inline void change(int x,int y,int mul,int add){    rever(x); access(y); splay(y);    val[y]=(val[y]*mul+add)%P;    sum[y]=(sum[y]*mul+size[y]*add)%P;    tag_mul[y]=(tag_mul[y]*mul)%P;    tag_add[y]=(tag_add[y]*mul+add)%P;}inline int query(int x,int y){    rever(x); access(y); splay(y);    return sum[y];}int main(){    n=read(); Q=read();    for (int i=1;i<=n;i++) val[i]=sum[i]=size[i]=tag_mul[i]=1;    for (int i=1;i<n;i++)    {        int u=read(),v=read();        link(u,v);    }    while (Q--)    {        char opt[5];        scanf("%s",opt);        int u=read(),v=read(),u0,v0,c;        switch (opt[0])        {            case '+':                c=read();                change(u,v,1,c);                break;            case '-':                u0=read(); v0=read();                cut(u,v); link(u0,v0);                break;            case '*':                c=read();                change(u,v,c,0);                break;            case '/':                printf("%d\n",query(u,v));                break;        }    }    return 0;}
2 0