简单树刨+线段树模板 877E - Danil and a Part-time Job
#include<bits/stdc++.h> using namespace std; const int maxn=200008; struct fuck{ int v,next; }edge[maxn]; int tol; int head[maxn]; void init() { tol=0; memset(head,-1,sizeof(head)); } void addedge(int u,int v) { edge[tol].v=v; edge[tol].next=head[u]; head[u]=tol++; } int li[maxn],ri[maxn]; int tim; int w[maxn]; int b[maxn]; void dfs(int u) { li[u]=++tim; b[tim]=w[u]; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; dfs(v); } ri[u]=tim; } int lazy[maxn<<2],a[maxn<<2]; void build(int x,int y,int c) { lazy[c]=0; if(x==y) { a[c]=b[x]; return; } int mid=(x+y)>>1; build(x,mid,c<<1); build(mid+1,y,c<<1|1); a[c]=a[c<<1]+a[c<<1|1]; } void pushdown(int x,int y,int c) { if(lazy[c]){ int mid=(x+y)>>1; a[c<<1]=mid-x+1-a[c<<1]; a[c<<1|1]=y-mid-a[c<<1|1]; lazy[c<<1]=lazy[c<<1]^1; lazy[c<<1|1]=lazy[c<<1|1]^1; lazy[c]=0; } } void update(int sx,int sy,int x,int y,int c) { if(sx<=x&&y<=sy) { lazy[c]=lazy[c]^1; a[c]=y-x+1-a[c]; return; } pushdown(x,y,c); int mid=(x+y)>>1; if(sx<=mid) update(sx,sy,x,mid,c<<1); if(sy>mid) update(sx,sy,mid+1,y,c<<1|1); a[c]=a[c<<1]+a[c<<1|1]; } int query(int sx,int sy,int x,int y,int c) { if(sx<=x&&y<=sy) { return a[c]; } pushdown(x,y,c); int mid=(x+y)>>1; int sum=0; if(sx<=mid) sum+=query(sx,sy,x,mid,c<<1); if(sy>mid) sum+=query(sx,sy,mid+1,y,c<<1|1); return sum; } int main() { int n; int u,v; while(scanf("%d",&n)==1) { init(); for(int i=2;i<=n;i++) { scanf("%d",&u); addedge(u,i); } for(int i=1;i<=n;i++) scanf("%d",&w[i]); tim=0;dfs(1); build(1,tim,1); int q; scanf("%d",&q); while(q--) { char s[18]; scanf("%s",s); scanf("%d",&u); if(s[0]=='g'){ int shit=query(li[u],ri[u],1,tim,1); printf("%d\n",shit); } else{ update(li[u],ri[u],1,tim,1); } } } return 0; }