/*
* 题目要求支持的操作有两种
* 安装操作就是将某节点和0号节点之间的路径上的所有节点数值都变为1
* 卸载操作就是将某节点为根的子树的所有节点数值变为0
* 输出的是每种操作之后,状态发生变化的节点数量,其实也就是操作前1的总数和操作后1总数的差值的绝对值
*
* 通过LCT将树上操作转换为线性区间操作,上面两种操作就是标准的线段树操作,线段树上维护好
* 懒标记和区间和即可
*
*/
#include <vector>
#include <algorithm>
#include <string.h>
using namespace std;
#define N (100008)
// LCT 相关定义
vector<int> link[N];
int dfs_id[N]; // 节点的dfs序id
int head_id[N]; // 节点对应的链的开始节点id
int fa[N]; // 父节点id
int sub_tree_start[N]; // 子树对应的dfs序区间开始位置
int sub_tree_end[N]; // 子树对应的dfs序区间结束为止
int dep[N]; // 节点深度
int heavy_child[N]; // 节点的重儿子节点id
int is_heavy[N]; // 节点是否是重儿子节点
// 线段树相关定义
int L[N<<2];
int R[N<<2];
long long val[N << 2];
long long add_flag[N << 2]; // lazy标记
void push_up(int idx) {
val[idx] = val[idx << 1] + val[(idx<<1) + 1];
}
void push_down(int idx) {
if (add_flag[idx] == -1) {
return;
}
int l = idx << 1, r = (idx << 1) + 1;
add_flag[l] = add_flag[idx];
val[l] = add_flag[idx] * (R[l] - L[l] + 1);
add_flag[r] = add_flag[idx];
val[r] = add_flag[idx] * (R[r] - L[r] + 1);
add_flag[idx] = -1;
}
void build_seg_tree(int idx, int start, int end) {
L[idx] = start, R[idx] = end, add_flag[idx] = 0;
if (start == end) {
val[idx] = 0;
return;
}
int mid = start + ((end-start) >> 1);
build_seg_tree(idx<<1, start, mid);
build_seg_tree((idx<<1)+1, mid+1, end);
push_up(idx);
}
// 区间值修改为k
void change_range(int idx, int start, int end, int k) {
if (start == L[idx] and end == R[idx]) {
add_flag[idx] = k;
val[idx] = k * (R[idx] - L[idx] + 1);
return;
}
push_down(idx);
int mid = L[idx] + ((R[idx]-L[idx]) >> 1);
if (end <= mid) {
change_range(idx << 1, start, end, k);
} else if (start >= mid+1) {
change_range((idx<<1) + 1, start, end, k);
} else {
change_range(idx <<1 , start, mid, k);
change_range((idx<<1) + 1, mid+1, end, k);
}
push_up(idx);
}
void add_edge(int a, int b) {
link[a].push_back(b);
link[b].push_back(a);
}
int dfs1(int cur, int prev, int d) {
fa[cur] = prev;
dep[cur] = d;
int tot_size = 1;
int max_s = -1, max_root = 0, s = 0;
for (auto next : link[cur]) {
if (next != prev) {
s = dfs1(next, cur, d+1);
if (s > max_s) {
max_s = s;
max_root = next;
}
tot_size += s;
}
}
heavy_child[cur] = max_root;
return tot_size;
}
void dfs2(int cur, int h, int prev, int& id) {
head_id[cur] = h;
dfs_id[cur] = id++;
if (heavy_child[cur]) {
dfs2(heavy_child[cur], h, cur, id);
}
for (auto next : link[cur]) {
if (next != prev && next != heavy_child[cur]) {
if (is_heavy[next]) {
dfs2(next, h, cur, id);
} else {
dfs2(next, next, cur, id);
}
}
}
sub_tree_start[cur] = dfs_id[cur];
sub_tree_end[cur] = id-1;
}
void build_lct() {
dfs1(1, 0, 1);
int id = 1;
dfs2(1, 1, 0, id);
}
// 修改区段上每一个节点的数值为0或者1
long long change_lct_ranges(int a, int b, int k) {
int ha, hb;
long long sum1, sum2;
long long t = val[1];
while (1) {
ha = head_id[a];
hb = head_id[b];
if (ha == hb) {
a = dfs_id[a], b = dfs_id[b];
if (a > b) {
swap(a, b);
}
change_range(1, a, b, k);
break;
} else {
if (dep[ha] < dep[hb]) {
swap(a, b);
swap(ha, hb);
}
change_range(1, dfs_id[ha], dfs_id[a], k);
a = fa[ha];
}
}
return abs(t - val[1]);
}
// 修改子树对应的区间上所有节点数值为0或者1
long long change_sub_tree_range(int node_id, int k) {
int start = sub_tree_start[node_id];
int end = sub_tree_end[node_id];
int t = val[1];
change_range(1, start, end, k);
return abs(t - val[1]);
}
int main(void) {
//freopen("/Users/grh/Programming/CLionProjects/Test/data.txt", "r", stdin);
int n, m, node;
scanf("%d", &n);
for (int i = 2; i <= n; i++) {
scanf("%d", &node);
node++;
add_edge(i, node);
}
build_lct();
build_seg_tree(1, 1, n);
scanf("%d", &m);
char cmd[20];
while (m--) {
scanf("%s %d", cmd, &node);
node++;
if (strcmp(cmd, "install") == 0) {
printf("%lld\n", change_lct_ranges(1, node, 1));
} else {
printf("%lld\n", change_sub_tree_range(node, 0));
}
}
return 0;
}