zoj 3686 线段树
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
Author: CUI, Tianyi
Contest: ZOJ Monthly, March 2013
先先序遍历 + 后序遍历把子树转为同一个区间内,然后线段树即可。
#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
#define LL long long
#define lson (p->lch)
#define rson (p->rch)
#define MAXN 111111
int n, m;
vector<int> g[MAXN];
struct node{
int l, r, num, todo;
node *lch, *rch;
}*root;
int tsp, l[MAXN], r[MAXN];
void dfs(int u){
l[u] = tsp++;
for(int i=0; i<g[u].size(); i++)
dfs(g[u][i]);
r[u] = tsp;
}
void push_up(node *p){ p->num = lson->num + rson->num; }
void push_down(node *p){
if(!p->todo) return;
p->todo = 0;
lson->num = lson->r - lson->l - lson->num;
rson->num = rson->r - rson->l - rson->num;
lson->todo ^= 1;
rson->todo ^= 1;
}
void build(node *&p, int l, int r){
p = new node;
p->l = l; p->r = r;
p->num = p->todo = 0;
if(l+1 == r){
lson = rson = NULL;
return;
}
int m = (l + r) >> 1;
build(lson, l, m);
build(rson, m, r);
}
int query(node *p, int l, int r){
if(l<=p->l && r>=p->r) return p->num;
int ret = 0;
int m = (l + r) >> 1;
push_down(p);
if(lson->r > l) ret += query(lson, l, r);
if(rson->l < r) ret += query(rson, l, r);
return ret;
}
void update(node *p, int l, int r){
if(l<=p->l && r>=p->r){
p->todo ^= 1;
p->num = p->r - p->l - p->num;
return;
}
int m = (l + r) >> 1;
push_down(p);
if(lson->r > l) update(lson, l, r);
if(rson->l < r) update(rson, l, r);
push_up(p);
}
void mfree(node *p){
if(lson) mfree(lson);
if(rson) mfree(rson);
delete p;
}
int main(){
while(scanf(" %d %d", &n, &m)==2){
int i, j;
for(i=1; i<=n; i++) g[i].clear();
for(i=2; i<=n; i++){
scanf(" %d", &j);
g[j].push_back(i);
}
tsp=1;
dfs(1);
build(root, 1, 1+n);
while(m--){
char t;
scanf(" %c %d", &t, &i);
if(t == 'q') printf("%d\n", query(root, l[i], r[i]));
else update(root, l[i], r[i]);
}
mfree(root);
printf("\n");
}
return 0;
}

浙公网安备 33010602011771号