數算實習 apple tree 樹狀陣列
阿新 • • 發佈:2018-12-14
Apple tree 樹有N個樹杈,它們通過分支連線。卡卡將樹杈編號為1到N,根始終編號為1.蘋果將在樹杈上生長,兩個蘋果不會在同一個樹杈上生長。卡卡想要了解一棵子樹上有多少蘋果。
輸入: 第一行包含一個整數N(N ≤100,000),這是樹中的樹杈的數量。 以下N - 1行每個包含兩個整數u和v,這意味著樹杈u和樹杈v通過分支連線。 下一行包含的整數M(M ≤100,000)。 以下M行每行包含一個資訊,它要麼是 “ C x ”,表示在樹杈x上是否存在蘋果的狀態發生改變。即如果樹杈上有蘋果,那麼卡卡就會吃掉它; 否則就長出一個新的蘋果。 或是 “ Q x ”表示查詢樹杈x上方子樹中的蘋果數量,包括叉子x上的蘋果(如果存在樹杈x上存在蘋果 最開始樹上長滿了蘋果
#include <iostream> #include <vector> using namespace std; int a[200002] = { 0 }; int c[200002] = { 0 }; int sta[100001]; int en[100001]; vector<int> s[100001]; int ti = 1; int n; void dfs(int i) //深搜構建陣列區間 { sta[i] = ti; a[sta[i]] = 1; ti++; for (int k = 0; k < s[i].size(); k++) { dfs(s[i][k]); } en[i] = ti; a[en[i]] = 1; ti++; } int lowbit(int x) { return x & -x; } void update(int x, int delta) //更新樹狀陣列 { for (int i = x; i <= 2 * n; i = i + lowbit(i)) { c[i] += delta; } } int calculate(int x) //求和 { int sum = 0; for (int i = x; i > 0; i = i - lowbit(i)) { sum += c[i]; } return sum; } int main() { char p; int number; int m; cin >> n; for (int i = 1; i <= n - 1; ++i) { int r, l; cin >> r >> l; s[r].push_back(l); } dfs(1); for (int i = 1; i <= 2 * n; ++i) for (int j = i - lowbit(i) + 1; j <= i; ++j) c[i]++; cin >> m; for (int i = 1; i <= m; i++) { cin >> p >> number; if (p == 'Q') { cout << (calculate(en[number]) - calculate(sta[number] - 1)) / 2 << endl; } else if (p == 'C') { int t = a[sta[number]]; a[sta[number]] = 1 - a[sta[number]]; update(sta[number], a[sta[number]] - t); t = a[en[number]]; a[en[number]] = 1 - a[en[number]]; update(en[number], a[en[number]] - t); } } return 0; }