Given a rooted tree, each node has a boolean (0 or 1) labeled on it. Initially, all the labels are 0.
We define this kind of operation: given a subtree, negate all its labels.
And we want to query the numbers of 1's of a subtree.
Input
Multiple test cases.
First line, two integer N and M, denoting the numbers of nodes and numbers of operations and queries.(1<=N<=100000, 1<=M<=10000)
Then a line with N-1 integers, denoting the parent of node 2..N. Root is node 1.
Then M lines, each line are in the format "o node" or "q node", denoting we want to operate or query on the subtree with root of a certain node.
Output
For each query, output an integer in a line.
Output a blank line after each test case.
Sample Input
3 2 1 1 o 2 q 1
Sample Output
1
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#include <cstdio>
#include <cstring>
#include <algorithm>
const long M=110000;
long sum[M<<4],col[M<<4],n,m;
long lnum[M<<1],rnum[M<<1],dfs_cnt;
long head[M<<1],Next[M<<1],to[M<<1],cnt;
void PushUp(long rt){
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void PushDown(long rt,long len){
if (col[rt]){
col[rt<<1]^=1; col[rt<<1|1]^=1;
sum[rt<<1]=len-(len>>1)-sum[rt<<1];
sum[rt<<1|1]=(len>>1)-sum[rt<<1|1];
col[rt]=0;
}
}
void build(long l,long r,long rt){
sum[rt]=col[rt]=0;
if (l==r)return;
long m=(l+r)>>1;
build(lson); build(rson);
PushUp(rt);
}
void update(long L,long R,long l,long r,long rt){
if (L<=l && r<=R){
col[rt]^=1; sum[rt]=(r-l+1)-sum[rt];
return;
}
long m=(l+r)>>1;
PushDown(rt,r-l+1);
if (L<=m) update(L,R,lson);
if (m<R) update(L,R,rson);
PushUp(rt);
}
long query(long L,long R,long l,long r,long rt){
if (L<=l && r<=R) return sum[rt];
PushDown(rt,r-l+1);
long m=(l+r)>>1,ans=0;
if (L<=m) ans+=query(L,R,lson);
if (m<R) ans+=query(L,R,rson);
return ans;
}
void init_edge(){
memset(head,-1,sizeof(head));
cnt=dfs_cnt=0;
}
void add_edge(long u,long v){
Next[cnt]=head[u]; to[cnt]=v; head[u]=cnt++;
}
void dfs(long u){
lnum[u]=++dfs_cnt;
for (long i=head[u];i!=-1;i=Next[i]){
long v=to[i];
dfs(v);
}
rnum[u]=dfs_cnt;
}
int main(){
while (~scanf("%d%d",&n,&m)){
init_edge();
for (long i=2;i<=n;++i){
long u;
scanf("%d",&u);
add_edge(u,i);
}
dfs(1);
build(1,dfs_cnt,1);
char c;
for (long i=1;i<=m;++i){
long u;
getchar();
scanf("%c %d",&c,&u);
if (c=='o') update(lnum[u],rnum[u],1,dfs_cnt,1);
else{
long ans=query(lnum[u],rnum[u],1,dfs_cnt,1);
printf("%d\n",ans);
}
}
printf("\n");
}
return 0;
}