洛谷 1501 [国家集训队]Tree II BZOJ 2631 Tree
【题解】
维护乘法标记和加法标记的LCT
1 #include<cstdio> 2 #include<algorithm> 3 #define Mod (51061) 4 #define N 100010 5 #define rg register 6 #define ls (c[u][0]) 7 #define rs (c[u][1]) 8 #define MOD(k) (k-=k>=Mod?Mod:0) 9 using namespace std; 10 int n,m,top,fa[N],c[N][2],rev[N],st[N],size[N]; 11 unsigned int val[N],del[N],mul[N],sum[N]; 12 struct edge{ 13 int u,v; 14 }e[N<<1]; 15 inline int read(){ 16 int k=0,f=1; char c=getchar(); 17 while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar(); 18 while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar(); 19 return k*f; 20 } 21 inline bool isroot(int u){return c[fa[u]][0]!=u&&c[fa[u]][1]!=u;} 22 inline bool which(int u){return c[fa[u]][1]==u;} 23 inline void pushup(int u){ 24 sum[u]=sum[ls]+sum[rs]+val[u]; sum[u]%=Mod; 25 size[u]=size[ls]+size[rs]+1; 26 } 27 inline void pushdown(int u){ 28 if(rev[u]){ 29 rev[u]=0; rev[ls]^=1; rev[rs]^=1; swap(ls,rs); 30 } 31 del[ls]*=mul[u]; del[ls]%=Mod; 32 del[rs]*=mul[u]; del[rs]%=Mod; 33 mul[ls]*=mul[u]; mul[ls]%=Mod; 34 mul[rs]*=mul[u]; mul[rs]%=Mod; 35 val[ls]*=mul[u]; val[ls]%=Mod; 36 val[rs]*=mul[u]; val[rs]%=Mod; 37 sum[ls]*=mul[u]; sum[ls]%=Mod; 38 sum[rs]*=mul[u]; sum[rs]%=Mod; 39 del[ls]+=del[u]; MOD(del[ls]); 40 del[rs]+=del[u]; MOD(del[rs]); 41 val[ls]+=del[u]; MOD(val[ls]); 42 val[rs]+=del[u]; MOD(val[rs]); 43 sum[ls]+=del[u]*size[ls]; sum[ls]%=Mod; 44 sum[rs]+=del[u]*size[rs]; sum[rs]%=Mod; 45 mul[u]=1; del[u]=0; 46 } 47 void rotate(int u){ 48 int f=fa[u],gf=fa[f],wh=which(u); 49 if(!isroot(f)) c[gf][which(f)]=u; 50 fa[u]=gf; fa[f]=u; fa[c[u][wh^1]]=f; 51 c[f][wh]=c[u][wh^1]; c[u][wh^1]=f; 52 pushup(f); pushup(u); 53 } 54 void splay(int u){ 55 st[top=1]=u; 56 for(rg int i=u;!isroot(i);i=fa[i]) st[++top]=fa[i]; 57 for(rg int i=top;i;i--) pushdown(st[i]); 58 while(!isroot(u)){ 59 if(!isroot(fa[u])) rotate(which(u)==which(fa[u])?fa[u]:u); 60 rotate(u); 61 } 62 } 63 inline void access(int u){ 64 for(rg int son=0;u;son=u,u=fa[u]) splay(u),c[u][1]=son,pushup(u); 65 } 66 inline void makeroot(int u){access(u); splay(u); rev[u]^=1;} 67 int find(int u){ 68 access(u); splay(u); 69 while(ls) u=ls; return u; 70 } 71 void split(int x,int y){makeroot(x); access(y); splay(y);} 72 void link(int x,int y){makeroot(x); fa[x]=y;} 73 void cut(int x,int y){ 74 split(x,y); int t=c[y][0]; 75 if(t==x&&!c[t][1]) fa[x]=0,c[y][0]=0; 76 else{ 77 while(c[t][1]) t=c[t][1]; 78 if(t==x) fa[x]=0,c[fa[t]][1]=0; 79 } 80 } 81 int main(){ 82 n=read(); m=read(); 83 for(rg int i=1;i<=n;i++) mul[i]=val[i]=1; 84 for(rg int i=1;i<n;i++){ 85 e[i].u=read(); e[i].v=read(); 86 link(e[i].u,e[i].v); 87 } 88 while(m--){ 89 char c=getchar(); 90 while(c!='*'&&c!='/'&&c!='+'&&c!='-') c=getchar(); 91 if(c=='+'){ 92 int u=read(),v=read(),c=read(); 93 split(u,v); 94 del[v]+=c; MOD(del[v]); 95 val[v]+=c; MOD(val[v]); 96 sum[v]+=c*size[v]; sum[v]%=Mod; 97 } 98 else 99 if(c=='-'){ 100 int u1=read(),v1=read(),u2=read(),v2=read(); 101 cut(u1,v1); link(u2,v2); 102 } 103 else 104 if(c=='/'){ 105 int u=read(),v=read(); 106 split(u,v); printf("%d\n",sum[v]%Mod); 107 } 108 else{ 109 int u=read(),v=read(),c=read(); 110 split(u,v); 111 val[v]*=c; val[v]%=Mod; 112 mul[v]*=c; mul[v]%=Mod; 113 del[v]*=c; del[v]%=Mod; 114 sum[v]*=c; sum[v]%=Mod; 115 } 116 } 117 return 0; 118 }