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
水题,先dfs,再线段树
/*
* File: main.cpp
* Author: Kevin
*
* Created on 2013年10月28日, 下午3:56
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<vector>
#include<utility>
using namespace std;
#define MAXN 100005
#define lson(x) (x<<1)
#define rson(x) (x<<1|1)
#define pret(x) (x>>1)
#define lens(x) (cord[x].second-cord[x].first+1)
typedef pair<int, int> pr;
vector<int>vt[MAXN];
pr mk[MAXN];
/**************线段树相关数组***************/
pr cord[MAXN<<2]; //区间端点
int sum[MAXN<<2]; //所求答案
int flag[MAXN<<2]; //延迟标记
/********线段树的最大值应该是点数4倍**********/
int id;
void dfs(int rt) {
mk[rt].first = ++id;
for (int i = 0; i < vt[rt].size(); i++) {
int v = vt[rt][i];
if (mk[v].first == 0)dfs(v);
}
mk[rt].second = id;
}
void pushup(int rt) {
sum[rt] = sum[lson(rt)] + sum[rson(rt)];
}
void pushdown(int rt) {
if (flag[rt]) {
flag[rt] = 0;
flag[lson(rt)] ^= 1;
flag[rson(rt)] ^= 1;
sum[lson(rt)] = lens(lson(rt)) - sum[lson(rt)];
sum[rson(rt)] = lens(rson(rt)) - sum[rson(rt)];
}
}
void build(int l, int r, int rt) {
cord[rt] = make_pair(l, r);
flag[rt] = sum[rt] = 0;
if (l == r)return;
int m = pret(l + r);
build(l, m, lson(rt));
build(m + 1, r, rson(rt));
}
void update(int l, int r, int rt) {
if (cord[rt].first >= l && cord[rt].second <= r) {
flag[rt] ^= 1;
sum[rt] = lens(rt) - sum[rt];
return;
}
pushdown(rt);
int m = pret(cord[rt].first + cord[rt].second);
if (l <= m)update(l, r, lson(rt));
if (r >= m + 1)update(l, r, rson(rt));
pushup(rt);
}
int query(int l, int r, int rt) {
if (cord[rt].first >= l && cord[rt].second <= r) {
return sum[rt];
}
int ret = 0;
int m = pret(cord[rt].first + cord[rt].second);
pushdown(rt);
if (l <= m)ret += query(l, r, lson(rt));
if (r >= m + 1)ret += query(l, r, rson(rt));
return ret;
}
int main(int argc, char** argv) {
int n, m;
while (~scanf("%d%d", &n, &m)) {
for (int i = 1; i <= n; i++)vt[i].clear();
for (int i = 2; i <= n; i++) {
int x;
scanf("%d", &x);
vt[x].push_back(i);
}
for (int i = 1; i <= n; i++)mk[i].first = 0;
id = 0;
dfs(1);
build(1, n, 1);
while (m--) {
char c; int x;
scanf("%*c%c%d", &c, &x);
if (c == 'o')
update(mk[x].first, mk[x].second, 1);
else
printf("%d\n", query(mk[x].first, mk[x].second, 1));
}
printf("\n");
}
return 0;
}