题意:一颗n个节点的树,每个点都有一个权值(0或者1),初始化为0,两个操作:1、取反以i为节点的子树的所有点的权值;2、求以i点为根的子树中1的个数。
思路:dfs将所有节点重新编号,然后就是普通的成段更新。
代码如下:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<stdio.h>
#include<math.h>
#include<vector>
#define N 100005
#define inf 0x7ffffff
#define eps 1e-9
#define pi acos(-1.0)
using namespace std;
vector<int> G[N];
int hash[N],num[N];
int id;
void dfs(int cur)
{
num[cur] = 1;
hash[cur] = id++;
int len = G[cur].size();
for(int i = 0; i < len; i++)
{
dfs(G[cur][i]);
num[cur] += num[ G[cur][i] ];
}
}
struct node
{
int l,r,flag,sum;
}tree[4*N];
void build(int o,int l,int r)
{
tree[o].l = l;
tree[o].r = r;
tree[o].flag = tree[o].sum = 0;
if(l == r) return;
int m = (l+r)/2;
build(2*o,l,m);
build(2*o+1,m+1,r);
}
void pushup(int o)
{
tree[o].sum = tree[2*o].sum + tree[2*o+1].sum;
}
void pushdown(int o)
{
if(tree[o].flag)
{
tree[2*o].flag ^= 1;
tree[2*o].sum = tree[2*o].r - tree[2*o].l + 1 - tree[2*o].sum;
tree[2*o+1].flag ^= 1;
tree[2*o+1].sum = tree[2*o+1].r - tree[2*o+1].l + 1 - tree[2*o+1].sum;
tree[o].flag = 0;
}
}
void update(int o,int x,int y)
{
if(x <= tree[o].l && tree[o].r <= y)
{
tree[o].sum = tree[o].r - tree[o].l + 1 - tree[o].sum;
tree[o].flag ^= 1;
return;
}
pushdown(o);
int m = (tree[o].l+tree[o].r)/2;
if(x <= m) update(2*o,x,y);
if(y > m) update(2*o+1,x,y);
pushup(o);
}
int query(int o,int x,int y)
{
if(x <= tree[o].l && tree[o].r <= y)
return tree[o].sum;
pushdown(o);
int m = (tree[o].l+tree[o].r)/2;
int ans = 0;
if(x <= m) ans += query(2*o,x,y);
if(y > m) ans += query(2*o+1,x,y);
// pushup(o);
return ans;
}
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
int n,m;
while(scanf("%d%d",&n,&m) != EOF)
{
int i;
for(i = 1; i <= n; i++) G[i].clear();
for(i = 2; i <= n; i++)
{
int x;
scanf("%d",&x);
G[x].push_back(i);//xµÄ¶ù×Ó½Úµã
}
id = 1;
dfs(1);
build(1,1,n);
while(m--)
{
char s[10];
int x;
scanf("%s%d",s,&x);
if(s[0] == 'o')
update(1,hash[x],hash[x]+num[x]-1);
else
printf("%d\n",query(1,hash[x],hash[x]+num[x]-1));
}
printf("\n");
}
return 0;
}