xtu数据结构 I. A Simple Tree Problem

I. A Simple Tree Problem

Time Limit: 3000ms
Memory Limit: 65536KB
64-bit integer IO format: %lld      Java class name: Main
 

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记录时间戳,也就是记录区间长度,恰好的包含关系,为建立线段树带来很大的方便,不需要建立N棵线段树,但以某一点为根节点的字孩子区间一定是父节点的区间的子区间。这样好的性质,恰好可以映射到线段树上。。。。。
 
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <vector>
 6 #include <climits>
 7 #include <algorithm>
 8 #include <cmath>
 9 #define LL long long
10 #define INF 0x3f3f3f
11 using namespace std;
12 const int maxn = 100010;
13 int n,m,id;
14 vector<int>g[maxn];
15 int len[maxn<<2],cnt[maxn<<2],mark[maxn<<2];
16 struct node{
17     int lt,rt;
18 }tree[maxn<<2];
19 void dfs(int u){
20     tree[u].lt = ++id;
21     for(int i = 0; i < g[u].size(); i++){
22         dfs(g[u][i]);
23     }
24     tree[u].rt = id;
25 }
26 void build(int lt,int rt,int v){
27     cnt[v] = mark[v] = 0;
28     len[v] = rt-lt+1;
29     if(lt == rt) return;
30     int mid = (lt+rt)>>1;
31     build(lt,mid,v<<1);
32     build(mid+1,rt,v<<1|1);
33 }
34 void push_down(int v){
35     if(mark[v]){
36         cnt[v<<1] = len[v<<1]-cnt[v<<1];
37         mark[v<<1] ^= 1;
38         cnt[v<<1|1] = len[v<<1|1]-cnt[v<<1|1];
39         mark[v<<1|1] ^= 1;
40         mark[v] = 0;
41     }
42 }
43 void update(int x,int y,int lt,int rt,int v){
44     if(lt >= x && rt <= y){
45         cnt[v] = len[v] - cnt[v];
46         if(lt == rt) return;
47         mark[v] ^= 1;
48         return;
49     }
50     push_down(v);
51     int mid = (lt+rt)>>1;
52     if(x <= mid) update(x,y,lt,mid,v<<1);
53     if(y > mid) update(x,y,mid+1,rt,v<<1|1);
54     cnt[v] = cnt[v<<1]+cnt[v<<1|1];
55 }
56 int query(int x,int y,int lt,int rt,int v){
57     int ans = 0;
58     if(x <= lt && rt <= y){
59         return cnt[v];
60     }
61     push_down(v);
62     int mid = (lt+rt)>>1;
63     if(x <= mid) ans += query(x,y,lt,mid,v<<1);
64     if(y > mid) ans += query(x,y,mid+1,rt,v<<1|1);
65     return ans;
66 }
67 int main(){
68     int i,temp;
69     char s;
70     while(~scanf("%d%d",&n,&m)){
71         for(i = 0; i <= n; i++)
72             g[i].clear();
73         for(i = 2; i <= n; i++){
74             scanf("%d",&temp);
75             g[temp].push_back(i);
76         }
77         id = 0;
78         dfs(1);
79         build(1,n,1);
80         while(m--){
81             cin>>s>>temp;
82             if(s == 'o'){
83                 update(tree[temp].lt,tree[temp].rt,1,n,1);
84             }else cout<<query(tree[temp].lt,tree[temp].rt,1,n,1)<<endl;
85         }
86         cout<<endl;
87     }
88     return 0;
89 }
View Code

 

posted @ 2014-07-21 20:33  狂徒归来  阅读(268)  评论(0编辑  收藏  举报