数算实习 apple tree 树状数组

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值