bzoj2631
题目不难理解,模型也就是比较经典的LCT;
但需要注意乘法标记和加法标记的下传。
(我难道会告诉你我因此wa了4,5遍吗?);
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<cmath> #include<algorithm> using namespace std; #define LL unsigned int #define FILE "dealing" #define up(i,j,n) for(LL i=(j);i<=(n);i++) LL read(){ int ch=getchar(),f=1,x=0; while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch<='9'&&ch>='0')x=(x<<1)+(x<<3)+ch-'0',ch=getchar(); return f*x; } const LL maxn=100100,inf=1000000000,mod=51061; LL n,m; LL fa[maxn],c[maxn][2],v[maxn],delet[maxn],w[maxn],ch[maxn],q[maxn],top,rev[maxn],siz[maxn]; struct node{LL y,next;}e[maxn<<1]; LL len=0,linkk[maxn]; void insert(LL x,LL y){e[++len].y=y;e[len].next=linkk[x];linkk[x]=len;} bool isroot(LL o){return c[fa[o]][1]!=o&&c[fa[o]][0]!=o;} void updata(LL x){v[x]=(v[c[x][1]]+v[c[x][0]]+w[x])%mod;siz[x]=(siz[c[x][0]]+siz[c[x][1]]+1)%mod;} void reve(LL x){swap(c[x][0],c[x][1]);rev[x]^=1;} void dele(LL x,LL t){delet[x]=(delet[x]+t)%mod,v[x]=(v[x]+t*siz[x])%mod,w[x]=(w[x]+t)%mod;} void cheng(LL x,LL c){v[x]=(v[x]*c)%mod,w[x]=(w[x]*c)%mod,ch[x]=(ch[x]*c)%mod,delet[x]=(delet[x]*c)%mod;} void downdata(LL x){ if(ch[x]!=1)cheng(c[x][0],ch[x]),cheng(c[x][1],ch[x]),ch[x]=1; if(delet[x])dele(c[x][0],delet[x]),dele(c[x][1],delet[x]),delet[x]=0; if(rev[x])rev[x]^=1,reve(c[x][0]),reve(c[x][1]); } void rotate(LL x){ LL y=fa[x],z=fa[y]; LL d=c[y][1]==x; if(!isroot(y))c[z][c[z][1]==y]=x; fa[x]=z,fa[y]=x;fa[c[x][d^1]]=y; c[y][d]=c[x][d^1],c[x][d^1]=y; updata(y);updata(x); } void splay(LL x){ q[++top]=x; for(LL i=x;!isroot(i);i=fa[i])q[++top]=fa[i]; while(top)downdata(q[top--]); while(!isroot(x)){ LL y=fa[x],z=fa[y]; if(!isroot(y)){ if(c[y][1]==x^c[z][1]==y)rotate(x); else rotate(y); } rotate(x); } } void access(LL x){ for(LL t=0;x;t=x,x=fa[x])splay(x),c[x][1]=t,updata(x); } void makeroot(LL x){ access(x),splay(x),reve(x); } void link(LL x,LL y){ makeroot(x),fa[x]=y; } void cut(LL x,LL y){ makeroot(x);access(y);splay(y);fa[x]=0;c[y][0]=0; } void build(LL x){ ch[x]=siz[x]=v[x]=w[x]=1; for(LL i=linkk[x];i;i=e[i].next){ if(fa[x]==e[i].y)continue; fa[e[i].y]=x; build(e[i].y); } } int main(){ freopen(FILE".in","r",stdin); freopen(FILE".out","w",stdout); n=read(),m=read(); up(i,1,n-1){ LL x=read(),y=read(); insert(x,y);insert(y,x); } build(1); char s[10];LL x,y,c,u1,u2,v1,v2; while(m--){ scanf("%s",s); if(s[0]=='+'){ x=read(),y=read(),c=read(); makeroot(x),access(y),splay(y); dele(y,c); } if(s[0]=='-'){ u1=read(),v1=read(),u2=read(),v2=read(); cut(u1,v1); link(u2,v2); } if(s[0]=='*'){ x=read(),y=read(),c=read(); makeroot(x);access(y);splay(y); cheng(y,c); } if(s[0]=='/'){ x=read(),y=read(); makeroot(x);access(y);splay(y); printf("%d\n",v[y]); } } printf("%d\n",clock()); return 0; }