POJ-3321-Apple Tree dfs序树状数组

具体题目是,POJ-3321,这里不给了;

数据先给了n;代表了一共有n个编号(对于n个结点);

大致题意是给一颗根节点为编号1的树,以及接下来的n-1条边(x,y) 根据discuss区描述这条边就是x to y,不用考虑y to x;(这不是重点)

再是m个操作(点修改and这个点的子树的结点个数查询);

3
1 2
1 3
3
Q 1
C 2
Q 1

dfs序 后 用树状数组或者线段树维护

vector< vector<int> >G(N);
注意这里我改成了这样建树,不然就TLE了 

看这个文章就明白了

#include<iostream>
#include<vector>
#include<cstring>
#define rep(i,l,r) for(int i=l;i<r;i++)
#define Rep(i,l,r) for(int i=l;i<=r;i++)
#define rrep(i,l,r) for(int i=r;i>=l;i--)
#define lc rt<<1
#define lson l,m,rt<<1
#define rc rt<<1|1
#define rson m+1,r,rt<<1|1
#define mp make_pair
#define pb push_back
#define all(x) x.begin(),x.end()
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e5+10;
int L[N],R[N],key;
bool noApple[N],vis[N];
vector< vector<int> > G(N);
int c[N];
int n;
int lbt(int x){return x&(-x);}
void update(int x,int v){while(x<=n){c[x]+=v;x+=lbt(x);}}
int query(int x){int ret=0;while(x>0){ret+=c[x];x-=lbt(x);}return ret;}
void dfs(int u){
    vis[u]=true;
    key++;
    L[u]=key;
    for(int i=0;i<G[u].size();i++){
        int v=G[u][i];
        if(!vis[v]){
            dfs(v);
        }
    }
    R[u]=key;
}

int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int q;
    int kase=0;
    while(~scanf("%d",&n)){
        //printf("Case %d: ",++kase);
        Rep(i,1,n)G[i].clear();
        memset(noApple,false,sizeof noApple);
        memset(vis,false,sizeof vis);
        int x,y;
        rep(i,0,n-1){scanf("%d%d",&x,&y);G[x].pb(y);G[y].pb(x);}
        dfs(1);
        Rep(i,1,n)update(i,1);
        scanf("%d",&q);char op[10];
        while(q--){
            scanf("%s%d",op,&x);
            if(op[0]=='Q') printf("%d\n",query(R[x])-query(L[x]-1));
            else {update(L[x],noApple[x]?1:-1);noApple[x]=!noApple[x];}
        }
    }
    return 0;
}

 

猜你喜欢

转载自blog.csdn.net/zhonglong_lin/article/details/75209003