(简化题意)要对题目中的 installinstallinstall 和 uninstalluninstalluninstall 理解清楚, installinstallinstall 是对该节点到 rootrootroot 路径上的所有点取1, uninstalluninstalluninstall 是对该节点所在子树取0。每次操作求出更改的节点个数。n,q≤105n,q\leq 10^5n,q≤105 。
在执行线段树的查找同时进行修改,写好模板一切都好说。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int n,m;
ll in(){
ll x=0,f=1;
char c;
do{
c=getchar();
if(c=='-')
f=-1;
}while(c>'9' || c<'0');
while(c>='0' && c<='9'){
x=(x<<3)+(x<<1)+c-'0';
c=getchar();
}
return x*f;
}
struct ST{
struct ST_node{
int l,r,sum,tag;
}nd[400005];
#define ls(p) p<<1
#define rs(p) p<<1|1
inline void push_up(int p){
nd[p].sum=nd[ls(p)].sum+nd[rs(p)].sum;
}
inline void add_tag(int p,int k){
nd[p].tag=k;
nd[p].sum=(k-1)*(nd[p].r-nd[p].l+1);
}
void push_down(int p){
if(nd[p].tag){
add_tag(ls(p),nd[p].tag);
add_tag(rs(p),nd[p].tag);
nd[p].tag=0;
}
}
void build(int l,int r,int p){
nd[p].l=l;
nd[p].r=r;
if(l==r)
return;
int mid=(l+r)>>1;
build(l,mid,ls(p));
build(mid+1,r,rs(p));
push_up(p);
}
ll install(int ql,int qr,int p,int k){
int l=nd[p].l;
int r=nd[p].r;
int ret=0;
if(ql<=l && r<=qr){
ret=nd[p].sum;
if(k==2)
ret=nd[p].r-nd[p].l+1-ret;
add_tag(p,k);
return ret;
}
push_down(p);
int mid=(l+r)>>1;
if(ql<=mid)
ret+=install(ql,qr,ls(p),k);
if(qr>mid)
ret+=install(ql,qr,rs(p),k);
push_up(p);
return ret;
}
}S;
struct Tree{
struct Tree_node{
int fa,sz,to,son,top,dep;
vector <int> v;
}nd[100005];
int cnt;
void DFS1(int x){
nd[x].sz=1;
nd[x].dep=nd[nd[x].fa].dep+1;
int mx=-1;
for(int i=0;i<nd[x].v.size();++i){
int y=nd[x].v[i];
DFS1(y);
nd[x].sz+=nd[y].sz;
if(nd[y].sz>mx){
mx=nd[y].sz;
nd[x].son=y;
}
}
}
void DFS2(int x,int top){
nd[x].top=top;
cnt++;
nd[x].to=cnt;
if(nd[x].son)
DFS2(nd[x].son,top);
for(int i=0;i<nd[x].v.size();++i){
int y=nd[x].v[i];
if(y==nd[x].son)
continue;
DFS2(y,y);
}
}
void operate(int op,int x){
if(op==2){
int y=0;
ll ret=0;
while(nd[x].top!=nd[y].top){
if(nd[nd[x].top].dep<nd[nd[x].top].dep)
swap(x,y);
ret+=S.install(nd[nd[x].top].to,nd[x].to,1,op);
x=nd[nd[x].top].fa;
}
if(nd[x].dep>nd[y].dep)
swap(x,y);
ret+=S.install(nd[x].to,nd[y].to,1,op);
printf("%lld\n",ret);
}
else{
printf("%lld\n",S.install(nd[x].to,nd[x].to+nd[x].sz-1,1,op));
}
}
}T;
int main(){
n=in();
for(int i=1;i<n;++i){
T.nd[i].fa=in();
T.nd[T.nd[i].fa].v.push_back(i);
}
T.DFS1(0);
T.DFS2(0,0);
S.build(1,n,1);
m=in();
while(m){
m--;
char c;
do{
c=getchar();
}while(c!='i' && c!='u');
int x=in();
if(c=='i'){
T.operate(2,x);
}
else{
T.operate(1,x);
}
}
return 0;
}