poj-3321-dfs序-线段树-邻接表

思路:用邻接表存图,卡vector【这里被卡哭了QAQ】,用dfs遍历的顺序重新给节点编号,遍历时记录儿子数目。用dfs序建立线段树,change的时候单点更新,查询某子树上的苹果树即是查询该节点[i, i+childnum]这个区间的苹果数目,i指dfs序。

 总结:邻接表出边入边傻傻搞不清楚QAQ

AC代码:

  1 #include <iostream>

  2 #include <cstdio>

  3 #include <vector>

  4 #include <cstring>

  5 #include <algorithm>

  6 using namespace std;

  7 #define maxn 200010

  8 #define lson l, m, rt<<1

  9 #define rson m+1, r, rt<<1|1

 10 struct node

 11 {

 12     int cnt, val, num;

 13 };

 14 int n, m;

 15 node arr[maxn];

 16 int u[maxn], v[maxn], next[maxn], first[maxn];

 17 bool vis[maxn];

 18 int sgt[maxn<<2];

 19 void init()

 20 {

 21     memset(vis, 0, sizeof(vis));

 22     for(int i = 0; i < n+10; i++)  first[i] = -1;

 23     int e = 0, i;

 24     for(i = 1; i < n; i++) {

 25         scanf("%d%d", &u[i], &v[i]);

 26         next[i] = first[u[i]];

 27         first[u[i]] = i;

 28         u[n-1+i] = v[i];

 29         v[n-1+i] = u[i];

 30         next[n-1+i] = first[u[n-1+i]];

 31         first[u[n-1+i]] = n-1+i;

 32     }

 33 }

 34 int dfs(int i, int &num)

 35 {//cout<<i<<" - "<<num<<endl;

 36     arr[i].val = 1;

 37     arr[i].cnt = 0;

 38     arr[i].num = num;

 39     vis[i] = 1;

 40     for(int j = first[i]; j != -1; j = next[j]) {

 41         if(!vis[v[j]]) { num++; arr[i].cnt += dfs(v[j], num);  }

 42     }

 43     return arr[i].cnt+1;

 44 }

 45 void push_up(int rt)

 46 {

 47     sgt[rt] = sgt[rt<<1] + sgt[rt<<1|1];

 48 }

 49 void build(int l, int r, int rt)

 50 {

 51     sgt[rt] = 1;

 52     if(l == r) return;

 53     int m = (r+l)>>1;

 54     build(lson);

 55     build(rson);

 56     push_up(rt);

 57 }

 58 void change(int l, int r, int rt, int pos)

 59 {

 60     if(l == r) {

 61         if(sgt[rt] == 1) sgt[rt] = 0;

 62         else sgt[rt] = 1;

 63         return;

 64     }

 65     int m = (r+l)>>1;

 66     if(pos <= m) change(lson, pos);

 67     else change(rson, pos);

 68     push_up(rt);

 69 }

 70 int query(int l, int r, int rt, int L, int R )

 71 {

 72     if(L <= l && r <= R) {

 73         return sgt[rt];

 74     }

 75     int res = 0;

 76     int m = (l+r)>>1;

 77     if(L <= m) res += query(lson, L, R);

 78     if(m < R) res += query(rson, L, R);

 79     return res;

 80 }

 81 void work()

 82 {

 83     if(n == 1) {

 84         int x = 1;

 85         scanf("%d", &m);

 86         char re; int k;

 87         while (m--) {

 88             getchar();

 89             scanf("%c%d", &re, &k);

 90             if(re == 'Q') {

 91                 printf("%d\n", x);

 92             }

 93             else {

 94                 if(x == 0) x = 1; else x = 0;

 95             }

 96         }

 97     }else {

 98         init();

 99         int xxx = 1;

100         dfs(1,xxx);

101         build(1, n, 1);

102         char re; int k;

103         scanf("%d", &m);

104         for (int i = 0; i < m; i++) {

105             getchar();

106             scanf("%c%d", &re, &k);

107             if(re == 'C') {

108                 change(1, n, 1, arr[k].num);

109             }

110             else {

111                 int res = query(1, n, 1, arr[k].num, arr[k].num+arr[k].cnt);

112                 printf("%d\n", res);

113             }

114         }

115     }

116 }

117 int main()

118 {

119     while(scanf("%d", &n) != EOF && n) work();

120     return 0;

121 }

122 /*

123 7

124 1 3

125 1 4

126 3 5

127 3 6

128 4 2

129 4 7

130 11

131 Q 2

132 Q 2

133 Q 1

134 C 3

135 Q 3

136 C 3

137 Q 3

138 C 4

139 Q 7

140 Q 4

141 Q 2

142 

143 */
View Code

 

你可能感兴趣的:(poj)