POJ 3321 DFS序+树状数组

树形转线性,然后用树状数组维护就行,单点更新,区间查询,但是辣鸡POJ卡vector窝日,所以用链式前向星存就行

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <set>
#include <map>
using namespace std;
#define ll long long
#define maxn 100005
#define maxm 200010
struct Edge
{
	int next, to;
	Edge() :next(0), to(0){ }
}edge[maxm];
int head[maxn], cnt = 0;
int idx[maxn];
int low[maxn];
bool vis[maxn];
bool apple[maxn];
int bit[maxn];
int N, M;
int pos = 0;
void add(int u, int v)
{
	edge[cnt].to = v;
	edge[cnt].next = head[u];
	head[u] = cnt++;
}
void DFSidx(int u)
{
	idx[u] = ++pos;
	vis[u] = true;
	for (int i = head[u]; i != -1; i=edge[i].next)
	{
		if (vis[edge[i].to])
			continue;
		DFSidx(edge[i].to);
	}
	low[u] = pos;
}
//更新点查询区间 
int query(int i)
{
	int sum = 0;
	while (i)
	{
		sum += bit[i];
		i -= i&(-i);
	}
	return sum;
}
void update(int i, int val)
{
	while (i <= N)
	{
		bit[i] += val;
		i += i&(-i);
	}
}
int main()
{
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	memset(head, -1, sizeof(int)*maxn);
	scanf("%d", &N);
	int u, v;
	for (int i = 0; i < N - 1; ++i)
	{
		scanf("%d%d", &u, &v);
		add(u, v);
		add(v, u);
	}
	DFSidx(1);

	scanf("%d", &M);
	int sum;
	char cmd[4];
	for (int i = 0; i < M; ++i)
	{
		scanf("%s%d", cmd, &u);
		if (cmd[0] == 'C')
		{
			if (apple[idx[u]])
			{
				update(idx[u], -1);
				apple[idx[u]] = false;
			}
			else
			{
				update(idx[u], 1);
				apple[idx[u]] = true;
			}
		}
		else
		{
			sum = query(low[u]) - query(idx[u] - 1);
			printf("%d\n", low[u] - idx[u] + 1 - sum);
		}
	}
	//system("pause");
	//while (1);
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值