rt,不开 O2 过不去。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
struct edge {
int v, next;
} e[N << 1];
int a[N], w[N], pos[N], sum[N], L[N], R[N], tag[N], head[N], fa[N], id[N], siz[N], top[N], depth[N], son[N];
int edge_cnt, n, q, u, v, x, cnt, awa, slen, sum1, sum2;
char opt[10];
inline void build() {
memset(tag, -1, sizeof tag);
slen = sqrt(n), awa = n / slen + (n % slen != 0);
for (int id = 1; id <= awa; id ++)
L[id] = (id - 1) * slen + 1, R[id] = id * slen;
R[awa] = n;
for (int id = 1; id <= awa; id ++)
for (int j = L[id]; j <= R[id]; j ++)
pos[j] = id, sum[id] += a[j];
}
inline void rebuild(int id) {
sum[id] = 0;
for (int i = L[id]; i <= R[id]; i ++)
sum[id] += a[i];
}
inline void pushdown(int id) {
if (!~tag[id]) return;
for (int i = L[id]; i <= R[id]; i ++)
a[i] = tag[id];
tag[id] = -1;
}
inline void change(int l, int r, int x) {
int lp = pos[l], rp = pos[r];
pushdown(lp), pushdown(rp);
if (lp == rp) {
for (int i = l; i <= r; i ++) a[i] = x;
return rebuild(lp);
}
for (int i = l; i <= R[lp]; i ++) a[i] = x;
for (int id = lp + 1; id < rp; id ++) tag[id] = x, sum[id] = slen * x;
for (int i = L[rp]; i <= r; i ++) a[i] = x;
rebuild(lp), rebuild(rp);
}
inline int query(int l, int r) {
int lp = pos[l], rp = pos[r], ans = 0;
pushdown(lp), pushdown(rp);
rebuild(lp), rebuild(rp);
if (lp == rp) {
for (int i = l; i <= r; i ++)
ans += a[i];
return ans;
}
for (int i = l; i <= R[lp]; i ++) ans += a[i];
for (int i = lp + 1; i < rp; i ++) ans += sum[i];
for (int i = L[rp]; i <= r; i ++) ans += a[i];
return ans;
}
void dfs1(int u, int f, int dep) {
fa[u] = f, siz[u] = 1, depth[u] = dep;
for (int i = head[u]; i; i = e[i].next) {
int v = e[i].v;
if (v == f) continue;
dfs1(v, u, dep + 1);
if (siz[v] > siz[son[u]])
son[u] = v;
siz[u] += siz[v];
}
}
void dfs2(int u, int topf) {
id[u] = ++ cnt, a[cnt] = w[u], top[u] = topf;
if (!son[u]) return;
dfs2(son[u], topf);
for (int i = head[u]; i; i = e[i].next) {
int v = e[i].v;
if (v == son[u] || v == fa[u]) continue;
dfs2(v, v);
}
}
inline int qRange(int u, int v) {
int ans = 0;
while (top[u] != top[v]) {
if (depth[top[u]] < depth[top[v]]) swap(u, v);
ans += query(id[top[u]], id[u]), u = fa[top[u]];
}
if (depth[u] > depth[v]) swap(u, v);
return ans + query(id[u], id[v]);
}
inline void updRange(int u, int v, int x) {
while (top[u] != top[v]) {
if (depth[top[u]] < depth[top[v]]) swap(u, v);
change(id[top[u]], id[u], x), u = fa[top[u]];
}
if (depth[u] > depth[v]) swap(u, v);
change(id[u], id[v], x);
}
inline int qTree(int u) {
return query(id[u], id[u] + siz[u] - 1);
}
inline void updTree(int u, int x) {
change(id[u], id[u] + siz[u] - 1, x);
}
inline void add(int u, int v) {
e[++ edge_cnt].v = v;
e[edge_cnt].next = head[u];
head[u] = edge_cnt;
}
inline int read() {
register int t = 1, a = 0;
register char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-') t = -1;
ch = getchar();
}
while (ch <= '9' && ch >= '0')
a = a * 10 + ch - '0', ch = getchar();
return a * t;
}
int main() {
n = read();
for (int i = 1; i < n; i ++)
add(read() + 1, i + 1);
q = read(), dfs1(1, 0, 1), dfs2(1, 1), build();
for (int i = 1; i <= q; i ++) {
scanf("%s", opt), u = read() + 1;
if (opt[0] == 'i') sum1 = qRange(1, u), updRange(1, u, 1), sum2 = qRange(1, u);
else sum1 = qTree(u), updTree(u, 0), sum2 = qTree(u);
printf("%d\n", abs(sum1 - sum2));
}
return 0;
}