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; }