1 #include <cstdio>
2 #include <cstring>
3 #include <iostream>
4 #include <algorithm>
5 #define MAX 600010
6 #define WORKPATH (root->son[1]->son[0])
7 using namespace std;
8
9 struct SplayTree{
10 long long val,sum,c,size;
11 long long plus,num,_num;
12 SplayTree *son[2],*father;
13
14 SplayTree(int _,int __);
15 SplayTree() {}
16 bool Check() {
17 return father->son[1] == this;
18 }
19 void Combine(SplayTree *a,bool dir) {
20 son[dir] = a;
21 a->father = this;
22 }
23 void Plus(int c);
24 void PushUp() {
25 sum = son[0]->sum + son[1]->sum + val * (plus ? 1:-1);
26 size = son[0]->size + son[1]->size + 1;
27 num = son[0]->num + son[1]->num + (plus == 1);
28 _num = son[0]->_num + son[1]->_num + (plus == 0);
29 }
30 void PushDown() {
31 if(c) {
32 son[0]->Plus(c);
33 son[1]->Plus(c);
34 c = 0;
35 }
36 }
37 }none,*nil = &none,*root,*tree[MAX];
38 SplayTree:: SplayTree(int _,int __) {
39 plus = __;
40 if(__ == 1) ++num;
41 if(__ == 0) ++_num;
42 val = _;
43 sum = _ * (plus ? 1:-1);
44 size = 1;
45 c = 0;
46 son[0] = son[1] = nil;
47 }
48 void SplayTree:: Plus(int _) {
49 if(this == nil) return ;
50 sum += _ * (num - _num);
51 val += _;
52 c += _;
53 }
54
55 int points,asks;
56 int head[MAX],total;
57 int next[MAX],aim[MAX];
58
59 int src[MAX],pos[MAX];
60 int from[MAX],cnt;
61 int p[MAX];
62
63 char c[10];
64
65 inline void Add(int x,int y)
66 {
67 next[++total] = head[x];
68 aim[total] = y;
69 head[x] = total;
70 }
71
72 void DFS(int x)
73 {
74 pos[++cnt] = src[x];
75 from[cnt] = x;
76 p[cnt] = true;
77 for(int i = head[x]; i; i = next[i])
78 DFS(aim[i]);
79 pos[++cnt] = src[x];
80 from[cnt] = x;
81 p[cnt] = false;
82 }
83
84 void Pretreatment()
85 {
86 nil->son[0] = nil->son[1] = nil->father = nil;
87 nil->val = nil->sum = nil->c = nil->size = 0;
88 p[0] = p[cnt + 1] = -1;
89 }
90
91 SplayTree *BuildTree(int l,int r)
92 {
93 if(l > r) return nil;
94 int mid = (l + r) >> 1;
95 SplayTree *re = new SplayTree(pos[mid],p[mid]);
96 if(p[mid]) tree[from[mid] << 1] = re;
97 else tree[from[mid] << 1|1] = re;
98 re->Combine(BuildTree(l,mid - 1),false);
99 re->Combine(BuildTree(mid + 1,r),true);
100 re->PushUp();
101 return re;
102 }
103
104 inline void Rotate(SplayTree *a,bool dir)
105 {
106 SplayTree *f = a->father;
107 f->PushDown(),a->PushDown();
108 f->son[!dir] = a->son[dir];
109 f->son[!dir]->father = f;
110 a->son[dir] = f;
111 f->father->son[f->Check()] = a;
112 a->father = f->father;
113 f->father = a;
114 f->PushUp();
115 if(root == f) root = a;
116 }
117
118 inline void Splay(SplayTree *a,SplayTree *aim)
119 {
120 while(a->father != aim) {
121 if(a->father->father == aim)
122 Rotate(a,!a->Check());
123 else if(!a->father->Check()) {
124 if(!a->Check())
125 Rotate(a->father,true),Rotate(a,true);
126 else Rotate(a,false),Rotate(a,true);
127 }
128 else {
129 if(a->Check())
130 Rotate(a->father,false),Rotate(a,false);
131 else Rotate(a,true),Rotate(a,false);
132 }
133 }
134 a->PushUp();
135 }
136
137 SplayTree *Find(SplayTree *a,int k)
138 {
139 a->PushDown();
140 if(a->son[0]->size >= k) return Find(a->son[0],k);
141 k -= a->son[0]->size;
142 if(k == 1) return a;
143 return Find(a->son[1],k - 1);
144 }
145
146 inline void SplaySeg(SplayTree *a,SplayTree *b)
147 {
148 int size_1,size_2;
149 Splay(a,nil);
150 size_1 = root->son[0]->size + 1;
151 Splay(b,nil);
152 size_2 = root->son[0]->size + 1;
153 Splay(Find(root,size_1 - 1),nil);
154 Splay(Find(root,size_2 + 1),root);
155 }
156
157 int main()
158 {
159 cin >> points;
160 for(int x,i = 2; i <= points; ++i) {
161 scanf("%d",&x);
162 Add(x,i);
163 }
164 for(int i = 1; i <= points; ++i)
165 scanf("%d",&src[i]);
166 DFS(1);
167 Pretreatment();
168 root = BuildTree(0,cnt + 1);
169 root->father = nil;
170 cin >> asks;
171 for(int x,y,i = 1; i <= asks; ++i) {
172 scanf("%s",c);
173 if(c[0] == ‘Q‘) {
174 scanf("%d",&x);
175 SplaySeg(tree[1 << 1],tree[x << 1]);
176 printf("%lld\n",WORKPATH->sum);
177 }
178 else if(c[0] == ‘C‘) {
179 scanf("%d%d",&x,&y);
180 SplaySeg(tree[x << 1],tree[x << 1|1]);
181 SplayTree *temp = WORKPATH;
182 WORKPATH = nil;
183 root->son[1]->PushUp();
184 root->PushUp();
185 Splay(tree[y << 1],nil);
186 int k = root->son[0]->size + 1;
187 Splay(Find(root,k + 1),root);
188 root->son[1]->Combine(temp,false);
189 root->son[1]->PushUp();
190 root->PushUp();
191 }
192 else {
193 scanf("%d%d",&x,&y);
194 SplaySeg(tree[x << 1],tree[x << 1|1]);
195 WORKPATH->Plus(y);
196 }
197 }
198 return 0;
199 }