物理学家小C的研究正遇到某个瓶颈。
他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅有一个依赖星球。主星球没有依赖星球。
我们定义依赖关系如下:若星球a的依赖星球是b,则有星球a依赖星球b.此外,依赖关系具有传递性,即若星球a依赖星球b,星球b依赖星球c,则有星球a依赖星球c.
对于这个神秘的星系中,小C初步探究了它的性质,发现星球之间的依赖关系是无环的。并且从星球a出发只能直接到达它的依赖星球b.
每个星球i都有一个能量系数wi.小C想进行若干次实验,第i次实验,他将从飞船上向星球di发射一个初始能量为0的能量收集器,能量收集器会从星球di开始前往主星球,并收集沿途每个星球的部分能量,收集能量的多少等于这个星球的能量系数。
但是星系的构成并不是一成不变的,某些时刻,星系可能由于某些复杂的原因发生变化。
有些时刻,某个星球能量激发,将使得所有依赖于它的星球以及他自己的能量系数均增加一个定值。还有可能在某些时刻,某个星球的依赖星球会发生变化,但变化后依然满足依赖关系是无环的。
现在小C已经测定了时刻0时每个星球的能量系数,以及每个星球(除了主星球之外)的依赖星球。接下来的m个时刻,每个时刻都会发生一些事件。其中小C可能会进行若干次实验,对于他的每一次实验,请你告诉他这一次实验能量收集器的最终能量是多少。
第一行一个整数n,表示星系的星球数。
接下来n-1行每行一个整数,分别表示星球2-n的依赖星球编号。
接下来一行n个整数,表示每个星球在时刻0时的初始能量系数wi.
接下来一行一个整数m,表示事件的总数。
事件分为以下三种类型。
(1)"Q di"表示小C要开始一次实验,收集器的初始位置在星球di.
(2)"C xi yi"表示星球xi的依赖星球变为了星球yi.
(3)"F pi qi"表示星球pi能量激发,常数为qi.
对于每一个事件类型为Q的事件,输出一行一个整数,表示此次实验的收集器最终能量。
n<=100000,m<=300000,1<di,xi<=n,wi,qi<=100000.保证操作合法。注意w_i>=0
1 #include<iostream>
2 #include<cstdio>
3 #include<algorithm>
4 #include<cstring>
5 #include<queue>
6 #define LL long long
7 using namespace std;
8 const int mxn=210010;
9 int read(){
10 int x=0,f=1;char ch=getchar();
11 while(ch<‘0‘ || ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
12 while(ch>=‘0‘ && ch<=‘9‘){x=x*10-‘0‘+ch;ch=getchar();}
13 return x*f;
14 }
15 struct edge{
16 int v,nxt;
17 }e[mxn<<1];
18 int hd[mxn],mct=0;
19 void add_edge(int u,int v){
20 e[++mct].v=v;e[mct].nxt=hd[u];hd[u]=mct;return;
21 }
22 int ind[mxn],out[mxn],dtime=0;
23 int st[mxn],top=0;
24 int w[mxn];
25 int L[mxn],R[mxn],D[mxn];
26 //入的数量 出的数量 标记
27 struct node{
28 int ch[2],fa;
29 LL val,smm;
30 LL mk;int sz;
31 }t[mxn];
32 int rot;
33 void DFS(int u){
34 ind[u]=++dtime;D[dtime]=1;t[dtime].val=D[dtime]*w[u];
35 for(int i=hd[u];i;i=e[i].nxt)
36 DFS(e[i].v);
37 out[u]=++dtime;D[dtime]=-1;t[dtime].val=D[dtime]*w[u];
38 return;
39 }
40 void update(int x,int v){
41 if(!x || !v)return;
42 t[x].val+=D[x]*v;t[x].smm+=(L[x]-R[x])*(LL)v;
43 t[x].mk+=v;
44 return;
45 }
46 void PD(int x){
47 if(!x)return;
48 update(t[x].ch[0],t[x].mk);
49 update(t[x].ch[1],t[x].mk);
50 t[x].mk=0;
51 return;
52 }
53 inline void pushup(int x){
54 if(!x)return;
55 int lc=t[x].ch[0],rc=t[x].ch[1];
56 t[x].smm=t[lc].smm+t[x].val+t[rc].smm;
57 L[x]=L[lc]+L[rc]+(D[x]==1);
58 R[x]=R[lc]+R[rc]+(D[x]!=1);
59 t[x].sz=t[lc].sz+t[rc].sz+1;
60 return;
61 }
62 void rotate(int x,int &k){
63 int y=t[x].fa,z=t[y].fa,lc,rc;
64 if(t[y].ch[0]==x)lc=0;else lc=1;rc=lc^1;
65 if(y==k)k=x;
66 else t[z].ch[t[z].ch[1]==y]=x;
67 t[x].fa=z; t[y].fa=x;
68 t[t[x].ch[rc]].fa=y;
69 t[y].ch[lc]=t[x].ch[rc];t[x].ch[rc]=y;
70 pushup(y);
71 return;
72 }
73 int stk[mxn],top1=0;
74 void Splay(int x,int &k){
75 stk[top1=1]=x;
76 for(int i=x;t[i].fa;i=t[i].fa)stk[++top1]=t[i].fa;
77 while(top1)PD(stk[top1--]);
78 while(x!=k){
79 int y=t[x].fa,z=t[y].fa;
80 if(y!=k){
81 if((t[z].ch[0]==y)^(t[y].ch[0]==x))rotate(x,k);
82 else rotate(y,k);
83 }
84 rotate(x,k);
85 }
86 pushup(x);
87 return;
88 }
89 /*
90 inline int find(int x,int num){
91 PD(x);
92 int lc=t[x].ch[0],rc=t[x].ch[1];
93 if(t[lc].size>=num)return find(lc,num);
94 if(t[lc].size+1==num)return x;
95 return find(rc,num-t[lc].size-1);
96 }*/
97 int find_max(int x){
98 while(t[x].ch[1])x=t[x].ch[1];return x;
99 }
100 int find_min(int x){
101 while(t[x].ch[0])x=t[x].ch[0];return x;
102 }
103 inline void split(int x,int y){
104 Splay(x,rot);
105 int l=find_max(t[x].ch[0]);
106 Splay(y,rot);
107 int r=find_min(t[y].ch[1]);
108 Splay(l,rot);Splay(r,t[l].ch[1]);
109 return;
110 }
111 int Build(int l,int r,int fa){
112 if(l>r)return 0;
113 int mid=(l+r)>>1,res=mid;
114 t[res].fa=fa;
115 if(l==r){
116 t[res].smm=t[res].val;
117 L[res]=(D[res]==1); R[res]=L[res]^1;
118 return res;
119 }
120 t[res].ch[0]=Build(l,mid-1,res);
121 t[res].ch[1]=Build(mid+1,r,res);
122 pushup(res);
123 return res;
124 }
125 void query(int x){
126 Splay(ind[1],rot);
127 Splay(ind[x],t[rot].ch[1]);
128 LL ans=t[ind[1]].val+t[ind[x]].val+t[t[ind[x]].ch[0]].smm;
129 printf("%lld\n",ans);
130 return;
131 }
132 void power(){
133 int x=read();int v=read();
134 Splay(ind[x],rot);
135 Splay(out[x],t[rot].ch[1]);
136 t[ind[x]].val+=D[ind[x]]*v;t[out[x]].val+=D[out[x]]*v;
137 update(t[out[x]].ch[0],v);
138 pushup(t[rot].ch[1]);pushup(rot);
139 return;
140 }
141 int n,m;
142 int main(){
143 int i,j,x,y;
144 n=read();
145 for(i=2;i<=n;i++){
146 x=read();add_edge(x,i);
147 }
148 for(i=1;i<=n;i++)w[i]=read();
149 DFS(1);
150 rot=Build(1,n<<1,0);
151 m=read();
152 char ch[3];
153 while(m--){
154 scanf("%s",ch);
155 switch(ch[0]){
156 case ‘Q‘:{x=read();query(x);break;}
157 case ‘C‘:{
158 x=read();y=read();//x to y;
159 split(ind[x],out[x]);
160 int fa=t[rot].ch[1],tmp=t[fa].ch[0];
161 t[fa].ch[0]=0;
162 pushup(fa);pushup(rot);
163 Splay(ind[y],rot);
164 Splay(find_min(t[rot].ch[1]),t[rot].ch[1]);
165 fa=t[rot].ch[1];
166 t[fa].ch[0]=tmp;
167 t[tmp].fa=fa; pushup(fa);pushup(rot);
168 break;
169 }
170 case ‘F‘:{power();break;}
171 }
172 }
173 return 0;
174 }