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 }