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棵线段树,但以某一点为根节点的字孩子区间一定是父节点的区间的子区间。这样好的性质,恰好可以映射到线段树上。。。。。
 
xtu数据结构 I. A Simple Tree Problem
 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

 

你可能感兴趣的:(simple)