首页 > 代码库 > poj-3321-dfs序-线段树-邻接表

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 7124 1 3125 1 4126 3 5127 3 6128 4 2129 4 7130 11131 Q 2132 Q 2133 Q 1134 C 3135 Q 3136 C 3137 Q 3138 C 4139 Q 7140 Q 4141 Q 2142 143 */
View Code

 

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