bzoj2631
非常好的一篇博客(LCT)
题解来源(LCT)
先抄了一遍板子【注意数据范围】
#include<cstdio> #include<cctype> #include<algorithm> #define ls tr[x][0] #define rs tr[x][1] #define ui unsigned int using namespace std; const ui maxn=100004,mod=51061; ui n,q,fa[maxn],tr[maxn][2],siz[maxn],sum[maxn],val[maxn],ad[maxn],mul[maxn],tmp[maxn]; bool rev[maxn]; inline bool isroot(int x){return tr[fa[x]][0]==x || tr[fa[x]][1]==x;} inline void pushup(int x){sum[x]=(val[x]+sum[ls]+sum[rs])%mod;siz[x]=1+siz[ls]+siz[rs];} inline void pushr(int x){swap(ls,rs);rev[x]^=1;} inline void _add(int x,int inc){val[x]=(val[x]+inc)%mod;ad[x]=(ad[x]+inc)%mod;(inc*=siz[x])%=mod;sum[x]=(sum[x]+inc)%mod;} inline void _mul(int x,int ml){sum[x]=(sum[x]*ml)%mod;val[x]=(val[x]*ml)%mod;ad[x]=(ad[x]*ml)%mod;mul[x]=(mul[x]*ml)%mod;} inline void pushdown(int x){ if(mul[x]!=1)_mul(ls,mul[x]),_mul(rs,mul[x]),mul[x]=1; if(ad[x])_add(ls,ad[x]),_add(rs,ad[x]),ad[x]=0; if(rev[x]){if(ls)pushr(ls);if(rs)pushr(rs);rev[x]=0;} } inline void read(ui &x){ char ch=getchar();x=0;int f=1; while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} x*=f; } inline void read(int &x){ char ch=getchar();x=0;int f=1; while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} x*=f; } inline void rotate(int x){ int f=fa[x],gfa=fa[f],whicx=tr[f][1]==x,flag=isroot(f); tr[f][whicx]=tr[x][whicx^1];if(tr[f][whicx])fa[tr[f][whicx]]=f; tr[x][whicx^1]=f;fa[f]=x; fa[x]=gfa;if(flag)tr[gfa][tr[gfa][1]==f]=x; pushup(f);pushup(x); } inline void splay(int x){ int f,gf,head=0,y=x;tmp[++head]=y; while(isroot(y))tmp[++head]=y=fa[y]; while(head)pushdown(tmp[head--]); while(isroot(x)){ f=fa[x];gf=fa[f]; if(isroot(f))rotate((tr[f][1]==x)==(tr[gf][1]==f)?f:x); rotate(x); } } inline void access(int x){for(int y=0;x;x=fa[y=x])splay(x),rs=y,pushup(x);} inline void makeroot(int x){access(x);splay(x);pushr(x);} inline void split(int x,int y){makeroot(x);access(y);splay(y);} inline void link(int x,int y){makeroot(x);fa[x]=y;} inline void cut(int x,int y){split(x,y);fa[x]=tr[y][0]=0;pushup(y);} inline void ada(int a,int b,int val){split(a,b);_add(b,val);} inline void mu(int a,int b,int val){split(a,b);_mul(b,val);} int main(){ char ch[10]; read(n);read(q); int a,b,c,d; for(int i=1;i<=n;i++)sum[i]=val[i]=mul[i]=1; for(int i=1;i<n;i++)read(a),read(b),link(a,b); while(q--){ scanf("%s",ch); switch(ch[0]){ case'+':read(a);read(b);read(c);ada(a,b,c);break; case'-':read(a);read(b);read(c);read(d);cut(a,b);link(c,d);break; case'/':read(a);read(b);split(a,b);printf("%d\n",sum[b]);break; case'*':read(a);read(b);read(c);mu(a,b,c); } } }