题解:水水哒AAA树啦
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<queue> 6 #include<cstring> 7 #define PAU putchar(' ') 8 #define ENT putchar('\n') 9 #define CH for(int d=0;d<=1;d++) if(ch[d]) 10 using namespace std; 11 const int maxn=100000+10,inf=-1u>>1; 12 struct info{int mi,mx,siz,sm;}null=(info){inf,-inf,0,0}; 13 struct tag{int mul,add;bool empty(){return (mul==1&&add==0);}}nulltag=(tag){1,0}; 14 info operator+(const info&a,const info&b){ 15 return (info){min(a.mi,b.mi),max(a.mx,b.mx),a.siz+b.siz,a.sm+b.sm}; 16 } 17 info operator+(const info&a,const tag&b){ 18 return a.siz?(info){a.mi*b.mul+b.add,a.mx*b.mul+b.add,a.siz,a.sm*b.mul+b.add*a.siz}:null; 19 } 20 tag operator+(const tag&a,const tag&b){ 21 return (tag){a.mul*b.mul,a.add*b.mul+b.add}; 22 } 23 struct snode{ 24 snode*ch[2],*fa; 25 info x,sm;tag od,all; 26 void init(){x=sm=null;od=all=nulltag;ch[0]=ch[1]=fa=NULL;return;} 27 snode(){x=sm=null;od=all=nulltag;ch[0]=ch[1]=fa=NULL;} 28 void addt(tag a){ 29 od=od+a;all=all+a;x=x+a;sm=sm+a;return; 30 } 31 void down(){ 32 if(!od.empty()){CH{ch[d]->addt(od);};od=nulltag;}return; 33 } 34 void update(){ 35 sm=x;CH{sm=sm+ch[d]->sm;}return; 36 } 37 }Splay[maxn],*root[maxn]; 38 int parent(snode*x,snode*&y){return (y=x->fa)?y->ch[1]==x?1:y->ch[0]==x?0:-1:-1;} 39 void rotate(snode*x){ 40 snode*y,*z;int d1=parent(x,y),d2=parent(y,z); 41 if(y->ch[d1]=x->ch[d1^1]) y->ch[d1]->fa=y; 42 y->fa=x;x->fa=z;x->ch[d1^1]=y; 43 if(d2!=-1) z->ch[d2]=x; 44 y->update();return; 45 } 46 void pushdown(snode*x){ 47 static snode*s[maxn];int top=0; 48 for(snode*y;;x=y){ 49 s[top++]=x;y=x->fa; 50 if(!y||(y->ch[0]!=x&&y->ch[1]!=x)) break; 51 } while(top--) s[top]->down();return; 52 } 53 snode*splay(snode*x){ 54 pushdown(x);snode*y,*z;int d1,d2; 55 while(true){ 56 if((d1=parent(x,y))<0) break; 57 if((d2=parent(y,z))<0){rotate(x);break;} 58 if(d1==d2) rotate(y),rotate(x); 59 else rotate(x),rotate(x); 60 } x->update();return x; 61 } 62 snode*join(snode*x,snode*y){ 63 if(!x)return y;if(!y)return x; 64 while(x->ch[1]) x->down(),x=x->ch[1]; 65 splay(x)->ch[1]=y;y->fa=x;x->update();return x; 66 } 67 struct node{ 68 node*ch[2],*fa,*s[2]; 69 info x,sm,sb,all;tag cha,tre;bool rev; 70 int id; 71 void revt(){ 72 swap(ch[0],ch[1]);swap(s[0],s[1]);rev^=1;return; 73 } 74 void chat(tag a){ 75 x=x+a;sm=sm+a;cha=cha+a;all=sm+sb;return; 76 } 77 void tret(tag a){ 78 tre=tre+a;sb=sb+a;all=sm+sb;if(root[id])root[id]->addt(a);return; 79 } 80 void down(){ 81 if(rev){CH{ch[d]->revt();}rev=false;} 82 if(!cha.empty()){CH{ch[d]->chat(cha);}cha=nulltag;} 83 if(!tre.empty()){CH{ch[d]->tret(tre);}tre=nulltag;} 84 return; 85 } 86 void update(){ 87 sm=x;sb=null; 88 if(root[id])sb=sb+root[id]->sm; 89 CH{sm=sm+ch[d]->sm;sb=sb+ch[d]->sb;} 90 all=sm+sb; 91 s[0]=ch[0]?ch[0]->s[0]:this; 92 s[1]=ch[1]?ch[1]->s[1]:this; 93 return; 94 } 95 }lct[maxn]; 96 int parent(node*x,node*&y){return (y=x->fa)?y->ch[1]==x?1:y->ch[0]==x?0:-1:-1;} 97 void rotate(node*x){ 98 node*y,*z;int d1=parent(x,y),d2=parent(y,z); 99 if(y->ch[d1]=x->ch[d1^1]) y->ch[d1]->fa=y; 100 y->fa=x;x->fa=z;x->ch[d1^1]=y; 101 if(d2!=-1) z->ch[d2]=x; 102 y->update();return; 103 } 104 void pushdown(node*x){ 105 static node*s[maxn];int top=0; 106 for(node*y;;x=y){ 107 s[top++]=x;y=x->fa; 108 if(!y||(y->ch[0]!=x&&y->ch[1]!=x)) break; 109 } while(top--) s[top]->down();return; 110 } 111 node*splay(node*x){ 112 pushdown(x);node*y,*z;int d1,d2; 113 while(true){ 114 if((d1=parent(x,y))<0) break; 115 if((d2=parent(y,z))<0){rotate(x);break;} 116 if(d1==d2) rotate(y),rotate(x); 117 else rotate(x),rotate(x); 118 } x->update();return x; 119 } 120 void detach(node*x){ 121 snode*p=x->ch[1]->s[0]->id+Splay;p->init(); 122 p->x=x->ch[1]->all;x->ch[1]=NULL; 123 int id=x->id; 124 p->ch[0]=root[id]; 125 if(root[id]) root[id]->fa=p; 126 p->update();root[id]=p;return; 127 } 128 void connect(node*x,node*y){ 129 snode*p=y->s[0]->id+Splay; 130 int id=x->id;splay(p); 131 if(p->ch[0]) p->ch[0]->fa=NULL; 132 if(p->ch[1]) p->ch[1]->fa=NULL; 133 root[id]=join(p->ch[0],p->ch[1]); 134 y->chat(p->all);y->tret(p->all);return; 135 } 136 node*access(node*x){ 137 node*ret=NULL; 138 for(;x;x=x->fa){ 139 splay(x);if(x->ch[1]) detach(x); 140 x->ch[1]=ret;if(ret) connect(x,ret); 141 (ret=x)->update(); 142 } return ret; 143 } 144 void makeroot(int x){access(x+lct)->revt();return;} 145 void link(int x,int y){ 146 makeroot(x);splay(lct+x)->fa=lct+y; 147 access(lct+y);splay(lct+y)->ch[1]=lct+x; 148 return; 149 } 150 void changesub(int x,int y,tag t){ 151 makeroot(x);access(lct+y);splay(lct+y); 152 lct[y].x=lct[y].x+t; 153 if(root[y]) root[y]->addt(t); 154 lct[y].update();return; 155 } 156 void changecha(int x,int y,tag t){ 157 makeroot(x);access(lct+y)->chat(t);return; 158 } 159 info querycha(int x,int y){ 160 makeroot(x);return access(lct+y)->sm; 161 } 162 info querysub(int x,int y){ 163 makeroot(x);access(lct+y);splay(lct+y);return root[y]?lct[y].x+root[y]->sm:lct[y].x; 164 } 165 int treeroot; 166 void cutfa(int x){ 167 node*t=(access(lct+x),splay(lct+x)); 168 t->ch[0]=t->ch[0]->fa=NULL;t->update();return; 169 } 170 void linkfa(int x,int fa){ 171 access(fa+lct);splay(lct+fa); 172 makeroot(x);splay(lct+x)->fa=lct+fa;lct[fa].update(); 173 snode*p=Splay+x;p->init();p->x=lct[x].all; 174 p->ch[0]=root[fa];if(root[fa]) root[fa]->fa=p; 175 root[fa]=p;p->update();return; 176 } 177 void splitfa(int r,int x,int fa){ 178 makeroot(r);if((access(lct+x),access(lct+fa))==lct+x) return; 179 cutfa(x);linkfa(x,fa);return; 180 } 181 int n,Q,p1[maxn],p2[maxn],A[maxn]; 182 void inittree(int*a){ 183 for(int i=1;i<=n;i++){ 184 lct[i].id=i; 185 lct[i].s[0]=lct[i].s[1]=lct+i; 186 lct[i].x=lct[i].sm=lct[i].all=(info){a[i],a[i],1,a[i]}; 187 lct[i].cha=lct[i].tre=nulltag; 188 } return; 189 } 190 inline int read(){ 191 int x=0,sig=1;char ch=getchar(); 192 while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();} 193 while(isdigit(ch))x=10*x+ch-'0',ch=getchar(); 194 return x*=sig; 195 } 196 inline void write(int x){ 197 if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x; 198 int len=0,buf[15];while(x)buf[len++]=x%10,x/=10; 199 for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return; 200 } 201 void init(){ 202 n=read();Q=read(); 203 for(int i=2;i<=n;i++) p1[i]=read(),p2[i]=read(); 204 for(int i=1;i<=n;i++) A[i]=read(); 205 inittree(A); 206 for(int i=2;i<=n;i++) link(p1[i],p2[i]); 207 treeroot=read();makeroot(treeroot); 208 return; 209 } 210 void work(){ 211 int x,y,z,tp; 212 while(Q--){ 213 tp=read();x=read(); 214 if(tp==0) y=read(),changesub(treeroot,x,(tag){0,y}); 215 else if(tp==1) makeroot(x),treeroot=x; 216 else if(tp==2) y=read(),z=read(),changecha(x,y,(tag){0,z}); 217 else if(tp==3) write(querysub(treeroot,x).mi),ENT; 218 else if(tp==4) write(querysub(treeroot,x).mx),ENT; 219 else if(tp==5) y=read(),changesub(treeroot,x,(tag){1,y}); 220 else if(tp==6) y=read(),z=read(),changecha(x,y,(tag){1,z}); 221 else if(tp==7) y=read(),write(querycha(x,y).mi),ENT; 222 else if(tp==8) y=read(),write(querycha(x,y).mx),ENT; 223 else if(tp==9) y=read(),splitfa(treeroot,x,y); 224 else if(tp==10) y=read(),write(querycha(x,y).sm),ENT; 225 else if(tp==11) write(querysub(treeroot,x).sm),ENT; 226 } 227 return; 228 } 229 void print(){ 230 return; 231 } 232 int main(){init();work();print();return 0;}