1. 程式人生 > >POJ-3321 Apple Tree---樹狀數組+DFS序

POJ-3321 Apple Tree---樹狀數組+DFS序

一段 end map -s tar math mat 都是 targe

題目鏈接:

https://vjudge.net/problem/POJ-3321

題目大意:

題目大意級是說,給你一顆樹,最初每個節點上都有一個蘋果,有兩種操作:修改(即修改某一個節點,修改時這一個節點蘋果從有到無,或從無到有)和查詢(查詢某一個節點他的子樹上有多少個蘋果)。

解題思路:

對樹的每個節點進行編號,按照先序遍歷進行編號,這樣可以處理出一段區間,使得區間內都是點i的子樹,求和的時候只要求區間和即可。

黑色是原來的編號,藍色為用先序遍歷得到的編號

超級坑的一點:

這裏用vector<int>G[maxn]會超時

用vector<vector<int> > G(maxn)就過了

技術分享圖片

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<iostream>
  4 #include<algorithm>
  5 #include<string>
  6 #include<cmath>
  7 #include<set>
  8 #include<queue>
  9 #include<map>
 10 #include<stack>
 11 #include<vector>
 12 #include<list>
 13
#include<deque> 14 #include<sstream> 15 #include<cctype> 16 #define REP(i, n) for(int i = 0; i < (n); i++) 17 #define FOR(i, s, t) for(int i = (s); i < (t); i++) 18 #define MEM(a, x) memset(a, x, sizeof(a)); 19 using namespace std; 20 typedef long long ll; 21 typedef unsigned long
long ull; 22 const int maxn = 1e5 + 10; 23 const double eps = 1e-10; 24 const int INF = 1 << 30; 25 const int dir[4][2] = {1,0,0,1,0,-1,-1,0}; 26 const double pi = 3.1415926535898; 27 int T, n, m, cases, tot; 28 int tree[maxn], lef[maxn], rig[maxn], s[maxn];///s數組記錄該節點是否有樹 29 vector<vector<int> >a(maxn); 30 void dfs(int x) 31 ///dfs給樹節點編號,分別編成左節點和右節點, 32 ///左節點就是本身,右節點是可到達的節點的最大編號, 33 ///之後查詢節點x的子樹就可以直接查詢[le[x], rig[x]]的區間和 34 { 35 lef[x] = tot; 36 for(int i = 0; i < a[x].size(); i++) 37 { 38 tot++; 39 dfs(a[x][i]); 40 } 41 rig[x] = tot; 42 } 43 int lowbit(int x) 44 { 45 return x&(-x); 46 } 47 int sum(int x) 48 { 49 int ret = 0; 50 while(x > 0) 51 { 52 ret += tree[x]; 53 x -= lowbit(x); 54 } 55 return ret; 56 } 57 int add(int x, int d) 58 { 59 while(x <= n) 60 { 61 tree[x] += d; 62 x += lowbit(x); 63 } 64 } 65 int main() 66 { 67 int x, y; 68 char c[5]; 69 while(scanf("%d", &n) != EOF) 70 { 71 MEM(lef, 0); 72 MEM(rig, 0); 73 MEM(s, 0); 74 MEM(tree, 0); 75 for(int i = 0; i < maxn; i++)a[i].clear(); 76 for(int i = 1; i < n; i++) 77 { 78 scanf("%d%d", &x, &y); 79 a[x].push_back(y); 80 } 81 tot = 1; 82 dfs(1); 83 for(int i = 1; i <= n; i++) 84 { 85 s[i] = 1; 86 add(i, 1); 87 } 88 scanf("%d", &m); 89 while(m--) 90 { 91 scanf("%s%d", c, &x); 92 if(c[0] == Q) 93 { 94 cout << sum(rig[x]) - sum(lef[x] - 1) << endl; 95 } 96 else if(c[0] == C) 97 { 98 if(s[x])add(lef[x], -1); 99 else add(lef[x], 1); 100 s[x] = !s[x];///更新該點是否有蘋果 101 } 102 } 103 } 104 return 0; 105 }

POJ-3321 Apple Tree---樹狀數組+DFS序