样例可以过,但是数据点一个没过。
// 为了方便,将所有下标 +1,即从 [0,n-1] 变为 [1,n]
#include <string>
#include <vector>
#include <memory>
#include <cstring>
#include <iostream>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
// #define DEBUG
const int N = 1e5 + 10;
const int INF = 2e9;
int n, q, cnt;
std::vector<int> g[N]; // 不包含父亲节点
int fa[N], dep[N], son[N], size[N], top[N], dfn[N], rnk[N];
void dfs1(int u) {
dep[u] = dep[fa[u]] + 1, size[u] = 1;
// 更新深度以及子树大小
for (auto v : g[u]) {
dfs1(v);
size[u] += size[v];
if (size[v] > size[son[u]]) son[u] = v;
// 当前没有重儿子或者这颗子树的大小大于重儿子子树的大小时,重儿子变为当前的儿子
}
}
void dfs2(int u, int ftop) {
top[u] = ftop, rnk[dfn[u] = ++cnt] = u;
if (!son[u]) return ;
dfs2(son[u], ftop);
for (auto v : g[u])
if (v != son[u]) dfs2(v, v);
}
// 动态开点线段树
struct TreeNode {
int w, lzy; // w 存储 1 的个数
std::unique_ptr<TreeNode> lson, rson;
TreeNode() : w(0), lzy(INF), lson(nullptr), rson(nullptr) {}
};
bool inRange(int l, int r, int L, int R) { return l >= L && r <= R; }
bool outRange(int l, int r, int L, int R) { return l > R || r < L; }
void maketag(std::unique_ptr<TreeNode> &u, int l, int r, int x) {
u->lzy = x;
if (x == 1) u->w = r - l + 1;
else u->w = 0;
}
void pushup(std::unique_ptr<TreeNode> &u) { u->w = u->lson->w + u->rson->w; }
void pushdown(std::unique_ptr<TreeNode> &u, int l, int r) {
if (!u->lson) u->lson = std::unique_ptr<TreeNode>(new TreeNode);
if (!u->rson) u->rson = std::unique_ptr<TreeNode>(new TreeNode);
if (u->lzy == INF) return ;
int mid = l + r >> 1;
maketag(u->lson, l, mid, u->lzy);
maketag(u->rson, mid + 1, r, u->lzy);
u->lzy = INF;
}
int query(std::unique_ptr<TreeNode> &u, int l, int r, int L, int R, int x) { // 查询 [l,r] 有多少个 x
if (outRange(l, r, L, R)) return 0;
if (inRange(l, r, L, R)) return (x == 1 ? u->w : r - l + 1 - u->w);
int mid = l + r >> 1;
pushdown(u, l, r);
return query(u->lson, l, mid, L, R, x) + query(u->rson, mid + 1, r, L, R, x);
}
void update(std::unique_ptr<TreeNode> &u, int l, int r, int L, int R, int x) { // [l,r] 赋值为 x
if (outRange(l, r, L, R)) return ;
if (inRange(l, r, L, R)) { maketag(u, l, r, x); return ; }
int mid = l + r >> 1;
pushdown(u, l, r);
update(u->lson, l, mid, L, R, x);
update(u->rson, mid + 1, r, L, R, x);
pushup(u);
}
int main() {
std::cin.tie(0)->sync_with_stdio(0);
std::cin >> n;
// 重儿子为 -1 表示当前没有重儿子
for (int i = 2; i <= n; ++i) {
std::cin >> fa[i]; // 可以直接读入 fa[i]
++fa[i];
g[fa[i]].push_back(i); // 存储 fa[i] 的所有儿子
}
dfs1(1);
dfs2(1, 1);
std::unique_ptr<TreeNode> root(new TreeNode);
std::string op; int x;
for (std::cin >> q; q; --q) {
std::cin >> op >> x, ++x;
if (op == "install") {
// 将 x-0 的路径上全部赋值为 1
int res = 0, y = 1;
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]]) std::swap(x, y);
res += query(root, 1, n, dfn[top[x]], dfn[x], 0);
update(root, 1, n, dfn[x], dfn[top[x]], 1);
x = fa[top[x]];
}
if (dfn[x] > dfn[y]) std::swap(x, y);
res += query(root, 1, n, dfn[x], dfn[y], 0);
update(root, 1, n, dfn[x], dfn[y], 1);
std::cout << res << '\n';
} else {
// 将 x 的子树(包含 x)全部赋值为 0
std::cout << query(root, 1, n, dfn[x], dfn[x] + size[x] - 1, 1) << '\n';
update(root, 1, n, dfn[x], dfn[x] + size[x] - 1, 0);
}
}
std::cout.flush();
return 0;
}