CF877E Danil and a Part-time Job
树剖然后线段树维护即可,维护取反操作本质就是交换 01 的个数即可。
代码:
#include<bits/stdc++.h>
using namespace std;
template <typename T>
inline void read(T &x){
x=0;char ch=getchar();bool f=false;
while(!isdigit(ch)){if(ch=='-'){f=true;}ch=getchar();}
while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
x=f?-x:x;
return ;
}
template <typename T>
inline void write(T x){
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10^48);
return ;
}
const int N=2e5+5;
struct TREE{
struct node{
int l,r;
int tag,val;
}tree[N<<2];
#define l(x) tree[(x)].l
#define r(x) tree[(x)].r
#define mid(x) (tree[(x)].l+tree[(x)].r>>1)
#define tag(x) tree[(x)].tag
#define val(x) tree[(x)].val
#define ls x<<1
#define rs x<<1|1
int a[N];
void pushdown(int x){
if(tag(x)){
tag(ls)^=1,val(ls)=r(ls)-l(ls)+1-val(ls);
tag(rs)^=1,val(rs)=r(rs)-l(rs)+1-val(rs);
tag(x)=0;
}
}
void Pushup(int x){
val(x)=val(ls)+val(rs);
}
void build(int x,int l,int r){
l(x)=l,r(x)=r;tag(x)=0;
if(l==r){val(x)=a[l];return;}
build(ls,l(x),mid(x));
build(rs,mid(x)+1,r(x));
Pushup(x);
}
void Modify(int x,int l,int r){
if(r<l(x)||r(x)<l)return;
if(l<=l(x)&&r(x)<=r){
tag(x)^=1;
val(x)=r(x)-l(x)+1-val(x);
return;
}
pushdown(x);
Modify(ls,l,r);
Modify(rs,l,r);
Pushup(x);
}
int Query(int x,int l,int r){
if(r<l(x)||r(x)<l)return 0;
if(l<=l(x)&&r(x)<=r)return val(x);
pushdown(x);
return Query(ls,l,r)+Query(rs,l,r);
}
}T;
int n,m,a;
struct Graph{
struct node{
int v,nex;
}e[N<<1];
int cnt,head[N];
void add(int x,int y){e[++cnt]=(node){y,head[x]};head[x]=cnt;}
int tot,dfn[N],siz[N];
void dfs(int x,int fa){
dfn[x]=++tot,siz[x]=1;
for(int i=head[x];i;i=e[i].nex) if(e[i].v!=fa)dfs(e[i].v,x),siz[x]+=siz[e[i].v];
}
}G;
signed main(){
read(n);
for(int i=1;i<n;i++) read(a),G.add(a,i+1);
G.dfs(1,0);
for(int i=1;i<=n;i++) read(a),T.a[G.dfn[i]]=a;
T.build(1,1,n);
read(m);
while(m--){
char op[5];scanf("%s",op);
int x;read(x);
if(op[0]=='g'){
write(T.Query(1,G.dfn[x],G.dfn[x]+G.siz[x]-1));
putchar('
');
}
else T.Modify(1,G.dfn[x],G.dfn[x]+G.siz[x]-1);
}
return 0;
}