洛谷 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 }
View Code

 

posted @ 2018-04-16 07:53  Driver_Lao  阅读(171)  评论(0编辑  收藏  举报