思路和题解差不多,就是把树上的节点扔到dfs序上处理,重链剖分,并拿线段树来维护区间覆盖、区间求和的操作。
没过样例......求大佬答疑qwq
#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
int n;
vector<int> tree[100020];
int cnt[100020],dfn[100020],dl,pos[100020],hson[100020],fa[100020],top[100020],dep[100020];
inline void swap(int &a,int &b){a^=b;b^=a;a^=b;}
inline int abs(int a){return a<0?-a:a;}
void dfs1(int x,int d){
cnt[x] = 1;
dep[x] = d;
for(int i=0;i<tree[x].size();i++){
int v = tree[x][i];
fa[v] = x;
dfs1(v,d+1);
cnt[x] += cnt[v];
if(cnt[hson[x]] < cnt[v]) hson[x] = v;
}
}
void dfs2(int x,int tp){
dfn[x] = ++dl;
pos[dl] = x;
top[x] = tp;
if(hson[x]) dfs2(hson[x],tp);
for(int i=0;i<tree[x].size();i++){
int v = tree[x][i];
if(v!=hson[x]) dfs2(v,v);
}
}
struct ivaltree{
int value[4*100010],lazy[4*100010];
void build(int l,int r,int a){
lazy[a] = -1;
value[a] = 0;
if(l==r) return;
int mid = (l+r)>>1;
build(l,mid,a<<1);
build(mid+1,r,a<<1|1);
}
inline void push_down(int l,int r,int a){
int mid = (l+r)>>1;
value[a<<1] = lazy[a]*(mid-l+1);
value[a<<1|1] = lazy[a]*(r-mid);
lazy[a<<1] = lazy[a];
lazy[a<<1|1] = lazy[a];
lazy[a] = -1;
}
inline void update(int a){value[a] = value[a<<1] + value[a<<1|1];}
void fugai(int L,int R,int l,int r,int a,int v){
if(L<=l&&r<=R){
lazy[a] = v;
value[a] = (r-l+1)*v;
return;
}
if(lazy[a]!=-1)push_down(l,r,a);
int mid = (l+r)>>1;
if(L<=mid) fugai(L,R,l,mid,a<<1,v);
if(mid+1<=R) fugai(L,R,mid+1,r,a<<1|1,v);
update(a);
}
int sum(int L,int R,int l,int r,int a){
if(L<=l&&r<=R) return value[a];
int ans=0;
if(lazy[a]!=-1)push_down(l,r,a);
int mid = (l+r)>>1;
if(L<=mid) ans += sum(L,R,l,mid,a<<1);
if(mid+1<=R) ans += sum(L,R,mid+1,r,a<<1|1);
update(a);
return ans;
}
void change(int l,int r,int a,int v){
int x=l,y=r;
while(top[x]!=top[y]){
if(dep[top[x]] < dep[top[y]]) swap(x,y);
fugai(dfn[top[x]],dfn[x],1,n,1,v);
x = fa[top[x]];
}
if(dep[x] > dep[y]) swap(x,y);
fugai(dfn[x],dfn[y],1,n,1,v);
update(a);
}
}itree;
int read(){
int num=0;
char c=getchar();
while(c<'0'||c>'9')c=getchar();
while('0'<=c&&c<='9') num=num*10+c-'0',c=getchar();
return num;
}
int main(){
n=read();
for(int i=2;i<=n;i++){
int a=read();
tree[a+1].push_back(i);
}
dfs1(1,1);
dfs2(1,1);
// printf("1");
itree.build(1,n,1);
int q=read();
while(q--){
char c[15];
scanf("%s",c+1);
int tmp = itree.value[1];
if(c[1]=='i'){
int x = read();
x++;
itree.fugai(1,dfn[x],1,n,1,1);
printf("%d\n",abs(tmp - itree.value[1]));
}
else{
int x = read();
x++;
itree.fugai(dfn[x],dfn[x]+cnt[x]-1,1,n,1,0);
printf("%d\n",abs(tmp - itree.value[1]));
}
}
return 0;
}