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
",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;
}
原文地址:https://www.cnblogs.com/fengxunling/p/10280269.html