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;
}