BZOJ2631: tree

给棵树,支持:连边删边,链加,链乘,链求和。

LCT??

  1 #include<string.h>
  2 #include<stdlib.h>
  3 #include<stdio.h>
  4 #include<math.h>
  5 //#include<assert.h>
  6 #include<algorithm> 
  7 //#include<iostream>
  8 //#include<bitset>
  9 using namespace std;
 10 
 11 int n,m;
 12 #define maxn 100011
 13 const int mod=51061;
 14 struct LCT
 15 {
 16     struct Node
 17     {
 18         int fa,son[2];
 19         bool rev; int add,mul;
 20         int size,v,sum;
 21     }a[maxn];
 22     void makeatree(int id)
 23     {
 24         a[id].fa=a[id].son[0]=a[id].son[1]=a[id].rev=0;
 25         a[id].add=0; a[id].v=a[id].sum=1; a[id].mul=a[id].size=1;
 26     }
 27     void up(int x)
 28     {
 29         if (!x) return;
 30         int &p=a[x].son[0],&q=a[x].son[1];
 31         a[x].sum=(a[p].sum+a[q].sum+a[x].v)%mod;
 32         a[x].size=a[p].size+a[q].size+1;
 33     }
 34     void revsingle(int x)
 35     {
 36         if (!x) return;
 37         a[x].rev^=1;
 38         int &p=a[x].son[0],&q=a[x].son[1];
 39         p^=q; q^=p; p^=q;
 40     }
 41     void addsingle(int x,int v)
 42     {
 43         if (!x) return;
 44         a[x].v+=v; a[x].v-=a[x].v>=mod?mod:0;
 45         a[x].add+=v; a[x].add-=a[x].add>=mod?mod:0;
 46         a[x].sum=(a[x].sum+1ll*a[x].size*v)%mod;
 47     }
 48     void mulsingle(int x,int v)
 49     {
 50         if (!x) return;
 51         a[x].v=1ll*a[x].v*v%mod;
 52         a[x].mul=1ll*a[x].mul*v%mod;
 53         a[x].add=1ll*a[x].add*v%mod;
 54         a[x].sum=1ll*a[x].sum*v%mod;
 55     }
 56     bool isroot(int x)
 57     {
 58         if (!a[x].fa) return 1;
 59         return (a[a[x].fa].son[0]!=x && a[a[x].fa].son[1]!=x);
 60     }
 61     void down(int x)
 62     {
 63         int &p=a[x].son[0],&q=a[x].son[1];
 64         if (a[x].rev) {revsingle(p); revsingle(q); a[x].rev=0;}
 65         if (a[x].mul!=1) {mulsingle(p,a[x].mul); mulsingle(q,a[x].mul); a[x].mul=1;}
 66         if (a[x].add) {addsingle(p,a[x].add); addsingle(q,a[x].add); a[x].add=0;}
 67     }
 68     int sta[maxn];
 69     void download(int x)
 70     {
 71         int top=0; for (;!isroot(x);x=a[x].fa) sta[++top]=x; sta[++top]=x;
 72         for (;top;top--) down(sta[top]);
 73     }
 74     void rotate(int x)
 75     {
 76         const int y=a[x].fa,z=a[y].fa;
 77         bool w=(x==a[y].son[0]);
 78         a[x].fa=z;
 79         if (!isroot(y)) a[z].son[y==a[z].son[1]]=x;
 80         a[y].son[w^1]=a[x].son[w];
 81         if (a[x].son[w]) a[a[x].son[w]].fa=y;
 82         a[x].son[w]=y;
 83         a[y].fa=x;
 84         up(y); up(z);
 85     }
 86     void splay(int x)
 87     {
 88         if (!x) return;
 89         download(x);
 90         while (!isroot(x))
 91         {
 92             const int y=a[x].fa,z=a[y].fa;
 93             if (!isroot(y))
 94             {
 95                 if ((y==a[z].son[0])^(x==a[y].son[0])) rotate(x);
 96                 else rotate(y);
 97             }
 98             rotate(x);
 99         }
100         up(x);
101     }
102     void access(int x)
103     {
104         int y=0,tmp=x;
105         while (x) {splay(x); a[x].son[1]=y; up(x); y=x; x=a[x].fa;}
106         splay(tmp);
107     }
108     void resetroot(int x)
109     {
110         access(x);
111         revsingle(x);
112     }
113     void link(int x,int y)
114     {
115         resetroot(x);
116         a[x].fa=y;
117     }
118     void cut(int x,int y)
119     {
120         resetroot(x);
121         access(y);
122         a[y].son[0]=a[x].fa=0;
123         up(y);
124     }
125     void Add(int x,int y,int v)
126     {
127         resetroot(x);
128         access(y);
129         addsingle(y,v);
130     }
131     void Mul(int x,int y,int v)
132     {
133         resetroot(x);
134         access(y);
135         mulsingle(y,v);
136     }
137     int query(int x,int y)
138     {
139         resetroot(x);
140         access(y);
141         return a[y].sum;
142     }
143 }t;
144 
145 int main()
146 {
147     scanf("%d%d",&n,&m);
148     for (int i=1;i<=n;i++) t.makeatree(i);
149     for (int i=1,x,y;i<n;i++)
150     {
151         scanf("%d%d",&x,&y);
152         t.link(x,y);
153     }
154     char c;int x,y,w,z;
155     while (m--)
156     {
157         while ((c=getchar())!='+' && c!='-' && c!='*' && c!='/');
158         if (c=='+')
159         {
160             scanf("%d%d%d",&x,&y,&z);
161             t.Add(x,y,z);
162         }
163         else if (c=='*')
164         {
165             scanf("%d%d%d",&x,&y,&z);
166             t.Mul(x,y,z);
167         }
168         else if (c=='-')
169         {
170             scanf("%d%d%d%d",&x,&y,&z,&w);
171             t.cut(x,y); t.link(z,w);
172         }
173         else if (c=='/')
174         {
175             scanf("%d%d",&x,&y);
176             printf("%d\n",t.query(x,y));
177         }
178     }
179     return 0;
180 }
View Code

 

posted @ 2018-01-16 07:55  Blue233333  阅读(115)  评论(0编辑  收藏  举报