bzoj2631 tree
Link cut tree
维护size和两个标记即可
黄学长告诉我long long 会T……
上面long long 下面unsigned……
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<string> 7 #include<cmath> 8 #include<ctime> 9 #include<queue> 10 #include<stack> 11 #include<map> 12 #include<set> 13 #define rre(i,r,l) for(int i=(r);i>=(l);i--) 14 #define re(i,l,r) for(int i=(l);i<=(r);i++) 15 #define Clear(a,b) memset(a,b,sizeof(a)) 16 #define inout(x) printf("%d",(x)) 17 #define douin(x) scanf("%lf",&x) 18 #define strin(x) scanf("%sum",(x)) 19 #define LLin(x) scanf("%lld",&x) 20 #define op operator 21 #define CSC main 22 typedef unsigned long long ULL; 23 typedef const int cint; 24 typedef long long LL; 25 using namespace std; 26 cint mod=51061; 27 void inin(int &ret) 28 { 29 ret=0;int f=0;char ch=getchar(); 30 while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();} 31 while(ch>='0'&&ch<='9')ret*=10,ret+=ch-'0',ch=getchar(); 32 ret=f?-ret:ret; 33 } 34 int ch[100010][2],rev[100010],fa[100010]; 35 unsigned w[100010],sum[100010],add[100010],cheng[100010],s[100010]; 36 bool isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;} 37 void maintain(int x) 38 { 39 if(x) 40 { 41 sum[x]=(w[x]+sum[ch[x][0]]+sum[ch[x][1]])%mod; 42 s[x]=1+s[ch[x][0]]+s[ch[x][1]]; 43 } 44 } 45 void addtag(int x,int a,int b) 46 { 47 w[x]=(w[x]*a+b)%mod; 48 sum[x]=(sum[x]*a+b*s[x])%mod; 49 add[x]=(add[x]*a+b)%mod; 50 cheng[x]=cheng[x]*a%mod; 51 } 52 void rotate(int x) 53 { 54 int y=fa[x],z=fa[y]; 55 if(!isroot(y))ch[z][ch[z][1]==y]=x; 56 fa[x]=z,fa[y]=x; 57 int d=ch[y][1]==x; 58 fa[ch[x][d^1]]=y; 59 ch[y][d]=ch[x][d^1]; 60 ch[x][d^1]=y; 61 maintain(y),maintain(x); 62 } 63 void down(int x) 64 { 65 if(rev[x]) 66 { 67 swap(ch[x][0],ch[x][1]); 68 rev[ch[x][0]]^=1; 69 rev[ch[x][1]]^=1; 70 rev[x]=0; 71 } 72 if(cheng[x]!=1||add[x]!=0) 73 { 74 addtag(ch[x][0],cheng[x],add[x]); 75 addtag(ch[x][1],cheng[x],add[x]); 76 } 77 add[x]=0;cheng[x]=1; 78 } 79 int sta[100010],top; 80 void splay(int x) 81 { 82 top=0;int xx=x;sta[++top]=xx; 83 while(!isroot(xx))sta[++top]=fa[xx],xx=fa[xx]; 84 while(top)down(sta[top--]); 85 while(!isroot(x)) 86 { 87 int y=fa[x],z=fa[y]; 88 if(!isroot(y)) 89 if((ch[y][1]==x)^(ch[z][1]==y))rotate(x); 90 else rotate(y);else ; 91 rotate(x); 92 } 93 } 94 void access(int x) 95 { 96 int temp=0; 97 while(x) 98 { 99 splay(x); 100 ch[x][1]=temp; 101 maintain(x); 102 temp=x,x=fa[x]; 103 } 104 } 105 void reverse(int x) 106 { 107 access(x),splay(x),rev[x]^=1; 108 } 109 void link(int x,int y) 110 { 111 reverse(x),fa[x]=y,splay(x); 112 } 113 void cut(int x,int y) 114 { 115 reverse(x),access(y),splay(y),ch[y][0]=fa[x]=0;maintain(y); 116 } 117 int n,m; 118 int main() 119 { 120 inin(n),inin(m); 121 re(i,1,n)s[i]=w[i]=sum[i]=cheng[i]=1; 122 re(i,2,n) 123 { 124 int x,y; 125 inin(x),inin(y); 126 link(x,y); 127 } 128 char ss[5]; 129 re(i,1,m) 130 { 131 strin(ss);int a,b,c,d; 132 if(ss[0]=='+') 133 { 134 inin(a),inin(b),inin(c); 135 reverse(a),access(b),splay(b); 136 addtag(b,1,c); 137 } 138 else if(ss[0]=='-') 139 { 140 inin(a),inin(b),inin(c),inin(d); 141 cut(a,b),link(c,d); 142 } 143 else if(ss[0]=='*') 144 { 145 inin(a),inin(b),inin(c); 146 reverse(a),access(b),splay(b); 147 addtag(b,c,0); 148 } 149 else 150 { 151 inin(a),inin(b); 152 reverse(a),access(b),splay(b); 153 printf("%d\n",sum[b]); 154 } 155 } 156 return 0; 157 }