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
#include<cstring>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<vector>
#include<algorithm>
#define lc idx<<1
#define rc idx<<1|1
#define lson l,mid,lc
#define rson mid+1,r,rc
#define N 100010
using namespace std;
int n,m;
vector<int>G[N];
int L[N],R[N],id;
struct Tree {
int st;
int one;
} tree[N<<2];
void init() {
for(int i=0; i<=n; i++)
G[i].clear();
id=1;
}
void dfs(int fa) {
L[fa]=id++;
for(int i=0; i<G[fa].size(); i++) {
dfs(G[fa][i]);
}
R[fa]=id-1;
}
void push_up(int idx) {
tree[idx].one=tree[lc].one+tree[rc].one;
}
void push_down(int idx,int m) {
if(tree[idx].st) {
tree[lc].st^=1,tree[rc].st^=1;
tree[idx].st=0;
tree[lc].one=m-m/2-tree[lc].one;
tree[rc].one=m/2-tree[rc].one;
}
}
void build(int l,int r,int idx) {
tree[idx].one=0;
tree[idx].st=0;
if(l==r)return;
int mid=(l+r)>>1;
build(lson);
build(rson);
}
void update(int l,int r,int idx,int x,int y) {
if(x<=l&&r<=y) {
tree[idx].st^=1;
tree[idx].one=r-l+1-tree[idx].one;
return;
}
push_down(idx,r-l+1);
int mid=(l+r)>>1;
if(x<=mid)update(lson,x,y);
if(y>mid) update(rson,x,y);
push_up(idx);
}
int query(int l,int r,int idx,int x,int y) {
if(x<=l&&r<=y)
return tree[idx].one;
push_down(idx,r-l+1);
int mid=(l+r)>>1;
int ans=0;
if(x<=mid) ans+=query(lson,x,y);
if(y>mid) ans+=query(rson,x,y);
return ans;
}
int main() {
//freopen("test.in","r",stdin);
while(~scanf("%d%d",&n,&m)) {
init();
int fa;
for(int i=2; i<=n; i++) {
scanf("%d",&fa);
G[fa].push_back(i);
}
dfs(1);
build(1,n,1);
char c[3];
int rt;
while(m--) {
scanf("%s%d",c,&rt);
if(c[0]=='o') {
update(1,n,1,L[rt],R[rt]);
continue;
}
printf("%d\n",query(1,n,1,L[rt],R[rt]));
}
printf("\n");
}
return 0;
}版权声明:本文为博主原创文章,未经博主允许不得转载。
ZOJ 3686 A Simple Tree Problem(线段树)
原文地址:http://blog.csdn.net/acm_baihuzi/article/details/47674851