0
点赞
收藏
分享

微信扫一扫

Apple Tree POJ3321 dfs序 + 树状数组

  • 题意
    卡卡屋前有一株苹果树,每年秋天,树上长了许多苹果。卡卡很喜欢苹果。树上有N个节点,卡卡给他们编号1到N,根的编号永远是1.每个节点上最多结一个苹果。卡卡想要了解某一个子树上一共结了多少苹果。现在的问题是不断会有新的苹果长出来,卡卡也随时可能摘掉一个苹果吃掉。你能帮助卡卡吗?

Apple Tree POJ3321 dfs序 + 树状数组_dfs序

  • 解题思路
    此题我们的想法肯定是想将查询和修改都降为Apple Tree POJ3321 dfs序 + 树状数组_数据结构_02的复杂度,这区间查询单点修改正好用树状数组或线段树解决即可。关键我们怎么将树转化为区间,即每颗子树都附上区间,Apple Tree POJ3321 dfs序 + 树状数组_dfs序_03可以帮我们解决这个问题,我们需要对每个结点设置一个Apple Tree POJ3321 dfs序 + 树状数组_dfs_04,这代表了我们从Apple Tree POJ3321 dfs序 + 树状数组_dfs_05结点出发的Apple Tree POJ3321 dfs序 + 树状数组_dfs序_03,即Apple Tree POJ3321 dfs序 + 树状数组_dfs_05Apple Tree POJ3321 dfs序 + 树状数组_dfs序_03序,而从Apple Tree POJ3321 dfs序 + 树状数组_dfs序_03完成之后Apple Tree POJ3321 dfs序 + 树状数组_dfs_05的子树也走完了,我们就要用Apple Tree POJ3321 dfs序 + 树状数组_数据结构_11来表示区间结束的编号。至此,通过Apple Tree POJ3321 dfs序 + 树状数组_dfs序_03编序即解决了这个问题。
  • AC代码
/**
*@filename:A
*@author: pursuit
*@created: 2021-08-11 21:09
**/
#include <iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#define debug(a) cout << "debug : " << (#a)<< " = " << a << endl

using namespace std;

typedef pair<int,int> pii;
typedef long long ll;
const int N = 1e5 + 10;
const int P = 1e9 + 7;
const int INF = 0x3f3f3f3f;

int n,m,u,v;
int ans[N],st[N],ed[N],num;//st[u]表示的为起始dfs序,ed[u]表示以u为结点的子树的终止dfs序,即子树的最大编号。
struct node{
int to,next;
}edges[N];
int tot,head[N];
bool vis[N];
void add(int u,int v){
edges[++tot].to = v;
edges[tot].next = head[u];
head[u] = tot;
}
void dfs(int u,int fu){
st[u] = ++ num;
for(int i = head[u]; i; i = edges[i].next){
int v = edges[i].to;
if(v == fu)continue;
dfs(v,u);
}
ed[u] = num;
}
int lowbit(int x){
return x & (- x);
}
void insert(int x,int value){
while(x <= n){
ans[x] += value;
x += lowbit(x);
}
}
int sum(int x){
int res = 0;
while(x > 0){
res += ans[x];
x -= lowbit(x);
}
return res;
}
void solve(){
dfs(1,1);
for(int i = 1; i <= n; ++ i){
insert(st[i],1);
}
scanf("%d", &m);
char op;
int x;
while(m -- ){
scanf(" %c%d", &op, &x);
if(op == 'C'){
insert(st[x],vis[x] ? -1 : 1);
vis[x] ^= 1;
}
else{
printf("%d\n", sum(ed[x]) - sum(st[x] - 1));
}
}
}
int main(){
scanf("%d", &n);
memset(vis,true,sizeof(vis));
memset(head,0,sizeof(head));
tot = num = 0;
for(int i = 1; i < n; ++ i){
scanf("%d%d", &u, &v);
add(u,v);
}
solve();
return 0;
}


举报

相关推荐

0 条评论