[bzoj3786] 星系探索
splay&&树的dfs序。。。这姿势太神了。
膜了半天题解。http://blog.csdn.net/PoPoQQQ/article/details/41649197
其实写那么久主要还是因为。。我的splay模版是含有size域的那种。。。在这题就用不了了TAT(或者说加了也没什么用。。)
改姿势感觉好蛋疼。。
比较奇怪的是我改成递归建树后只快了不到1s= =。。时限40s我跑了39+s。。
很好奇别人2K+代码是怎么写的= =
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #define ll long long 5 using namespace std; 6 const int maxn=100233; 7 struct zs{int too,pre;}e[maxn]; 8 int tot,last[maxn]; 9 int l[maxn],r[maxn],tim; 10 int ch[maxn<<1][2],numl[maxn<<1],numr[maxn<<1],fa[maxn<<1],v[maxn<<1],cnt; 11 ll sum[maxn<<1],add[maxn<<1]; 12 int st[maxn<<1],top; 13 int gg[maxn<<1],val[maxn]; 14 int i,j,k,n,m,x,y,rt; 15 int ra,fh;char rx,id; 16 inline int read(){ 17 rx=getchar(),ra=0,fh=1; 18 while((rx<'0'||rx>'9')&&rx!='-')rx=getchar(); 19 if(rx=='-')fh=-1,rx=getchar(); 20 while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra*fh; 21 } 22 inline void _add(int x,int q){ 23 if(gg[x]==1)v[x]+=q;else if(gg[x]==2)v[x]-=q; 24 sum[x]+=(ll)(numl[x]-numr[x])*q, 25 add[x]+=q; 26 } 27 inline void upd(int x){ 28 int l=ch[x][0],r=ch[x][1]; 29 sum[x]=sum[l]+sum[r]+v[x], 30 numl[x]=numl[l]+numl[r]+(gg[x]==1), 31 numr[x]=numr[l]+numr[r]+(gg[x]==2); 32 } 33 inline void pushdown(int x){ 34 if(!add[x])return; 35 if(ch[x][0])_add(ch[x][0],add[x]); 36 if(ch[x][1])_add(ch[x][1],add[x]); 37 add[x]=0; 38 } 39 inline void rotate(int x){ 40 int f=fa[x],gfa=fa[f],l=ch[f][1]==x,r=l^1; 41 if(f!=rt)ch[gfa][ch[gfa][1]==f]=x;else rt=x; 42 fa[fa[fa[ch[f][l]=ch[x][r]]=ch[x][r]=f]=x]=gfa,upd(f); 43 } 44 inline void splay(int &rt,int x){ 45 int f,gfa; 46 for(st[top=1]=f=x;fa[f];st[++top]=(f=fa[f])); 47 while(top)pushdown(st[top--]); 48 while(x!=rt){ 49 f=fa[x],gfa=fa[f]; 50 if(f!=rt) 51 rotate((ch[f][1]==x)!=(ch[gfa][1]==f)?x:f); 52 rotate(x); 53 } 54 upd(x); 55 } 56 inline int getmn(int x){while(ch[x][0])x=ch[x][0];return x;} 57 inline int getmx(int x){while(ch[x][1])x=ch[x][1];return x;} 58 inline int split(int x,int y){ 59 int a,b; 60 splay(rt,x),a=getmx(ch[x][0]); 61 splay(rt,y),b=getmn(ch[y][1]); 62 splay(rt,a),splay(ch[a][1],b); 63 return ch[b][0]; 64 } 65 inline void move(int a,int b){ 66 int x,y,z=split(l[a],r[a]); 67 x=rt,y=ch[x][1], 68 ch[y][0]=0,upd(y),upd(x); 69 x=l[b],splay(rt,x),y=getmn(ch[x][1]), 70 splay(ch[x][1],y),ch[y][0]=z,fa[z]=y,upd(y),upd(x); 71 } 72 inline ll query(int a){x=split(l[1],l[a]);return sum[x];} 73 inline void change(int p,int q){int x=split(l[p],r[p]);_add(x,q);} 74 inline void insert(int a,int b){e[++tot].too=b,e[tot].pre=last[a],last[a]=tot;} 75 inline void dfs(int x){ 76 l[x]=++tim;gg[tim]=1,v[tim]=val[x]; 77 for(int i=last[x];i;i=e[i].pre)dfs(e[i].too); 78 r[x]=++tim;gg[tim]=2,v[tim]=-val[x]; 79 } 80 inline void build(int a,int b,int pre){ 81 if(a>b)return; 82 int mid=(a+b)>>1; 83 if(pre)ch[pre][mid>pre]=mid; 84 fa[mid]=pre, 85 build(a,mid-1,mid),build(mid+1,b,mid); 86 upd(mid); 87 } 88 int main(){ 89 tim=1;rt=1;gg[rt]=3;upd(rt); 90 n=read(); 91 for(i=2;i<=n;i++)insert(read(),i); 92 for(i=1;i<=n;i++)val[i]=read(); 93 dfs(1); 94 tim++;gg[tim]=3; 95 build(1,tim,0);rt=(1+tim)>>1; 96 for(m=read();m;m--){ 97 for(id=getchar();id<'A'||id>'Z';id=getchar()); 98 x=read();if(id!='Q')y=read(); 99 if(id=='Q')printf("%lld\n",query(x)); 100 if(id=='F')change(x,y); 101 if(id=='C')move(x,y); 102 } 103 return 0; 104 }