POJ3321 Apple tree
是一个dfs序列的应用。我是来水博客的???
具体的讲解以及其他的一些应用请看我的这篇学习笔记 戳我 我又在推销博文了qwq
其实就是在对树进行dfs序遍历之后,它的每个子树都在一个区间以内(好吧,你要说树链剖分轻松搞定。。。。但是以来那个不也是有这种思想,二来树链剖分好长,不觉得大材小用了嘛。。。)
然后树状数组维护就可以了。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 100010
using namespace std;
int n,m,t,cnt;
int tree[MAXN<<1],head[MAXN],ru[MAXN],chu[MAXN],a[MAXN];
struct Edge{int nxt,to;}edge[MAXN<<1];
inline void addedge(int from,int to){edge[++t].nxt=head[from],edge[t].to=to,head[from]=t;}
inline void add(int x,int k)
{
for(int i=x;i<=n;i+=i&(-i))
tree[i]+=k;
}
inline int query(int x)
{
int cur_ans=0;
for(int i=x;i;i-=i&(-i))
cur_ans+=tree[i];
return cur_ans;
}
inline void search(int x,int fa)
{
ru[x]=++cnt;
for(int i=head[x];i;i=edge[i].nxt)
{
int v=edge[i].to;
if(v==fa) continue;
search(v,x);
}
chu[x]=cnt;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<n;i++)
{
int u,v;
scanf("%d%d",&u,&v);
addedge(u,v),addedge(v,u);
}
search(1,0);
for(int i=1;i<=n;i++) a[i]=1,add(i,1);
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
char cur;
int x;
cin>>cur;
if(cur=='Q')
{
scanf("%d",&x);
printf("%d\n",query(chu[x])-query(ru[x]-1));
}
else
{
scanf("%d",&x);
if(a[x]==1) a[x]=0,add(ru[x],-1);
else a[x]=1,add(ru[x],1);
}
}
return 0;
}