首页 > 代码库 > 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 */
poj-3321-dfs序-线段树-邻接表
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。