rt,调吐了 qwq
#include<bits/stdc++.h>
using namespace std;
const int N=100050,M=200050;
int n,m,r;
int fa[N],size[N],dep[N],son[N],dfn[N],top[N];
int val[N];
struct Node {
int to,next;
}arr[M];
int first[N],p;
void add(int u,int v) {
arr[++p].to=v;
arr[p].next=first[u];
first[u]=p;
}
struct Tree {
int l,r;
long long add,sum;
}tre[N*4];
inline int ls(int p){return p<<1;}
inline int rs(int p){return p<<1|1;}
void pushup(int u) {tre[u].sum=(tre[ls(u)].sum+tre[rs(u)].sum);}
void pushdown(int u) {
auto &root=tre[u],&lson=tre[ls(u)],&rson=tre[rs(u)];
if(root.add!=-1) {
lson.add+=root.add,lson.sum+=root.add*(lson.r-lson.l+1);
rson.add+=root.add,rson.sum+=root.add*(rson.r-rson.l+1);
root.add=0;
}
// cout << "123123fsdfs" << endl;
}
void build(int u,int l,int r) {
tre[u].l=l,tre[u].r=r,tre[u].add=0,tre[u].sum=0;
if(l==r) return;
int mid=(l+r)/2;
build(ls(u),l,mid);
build(rs(u),mid+1,r);
}
void plu(int u,int l,int r,int k) {
if(l<=tre[u].l&&r>=tre[u].r) tre[u].add=k,tre[u].sum=k*(tre[u].r-tre[u].l+1);
else {
pushdown(u);
int mid=(tre[u].l+tre[u].r)/2;
if(l<=mid) plu(ls(u),l,r,k);
if(mid<r) plu(rs(u),l,r,k);
pushup(u);
}
}
void dfs1(int u,int depth) {
// if(u==0) return;
size[u]=1;
dep[u]=depth;
int mson=0;
for(int i=first[u];i;i=arr[i].next) {
dfs1(arr[i].to,depth+1);
size[u]+=size[arr[i].to];
if (son[u]==0||size[son[u]]<size[arr[i].to]) son[u]=arr[i].to;
else if (size[son[u]]==size[arr[i].to]&&son[u]>arr[i].to) son[u]=arr[i].to;
}
}
int cnt;
void dfs2(int u,int f) {
top[u]=f;
dfn[u]=++cnt;
if(son[u]==0) return;
dfs2(son[u],f);
for(int i=first[u];i;i=arr[i].next) {
if(arr[i].to==son[u]) continue;
dfs2(arr[i].to,arr[i].to);
}
}
void plus_path(int u,int v,int k) {
while(top[u]!=top[v]) {
if(dep[top[u]]<dep[top[v]]) swap(u,v);
plu(1,dfn[top[u]],dfn[u],k);
u=fa[top[u]];
}
if(dep[u]>dep[v]) swap(u,v);
plu(1,dfn[u],dfn[v],k);
}
void plus_tree(int u,int k) {
plu(1,dfn[u],dfn[u]+size[u]-1,k);
}
int main() {
int n,x;
cin >> n;
for(int i=2;i<=n;++i) {
cin >> x;
x++;
add(x,i);
fa[i]=x;
}
build(1,1,n);
dfs1(1,1); //遍历到的节点,该节点的父亲节点
// cout << "热i法国火热" << endl;
dfs2(1,1); //遍历到的节点,该节点所在链的顶点
int m;
cin >> m;
string s;
while(m--) {
cin >> s;
int a=tre[1].sum;
if(s=="install") {
cin >> x;
x++;
plus_path(1,x,1);
cout << abs(tre[1].sum-a) << endl;
}else {
cin >> x;
x++;
plus_tree(x,0);
cout << abs(tre[1].sum-a) << endl;
}
}
return 0;
}
找了半天没找出错...