1. 程式人生 > >POJ-3321-Apple Tree dfs序樹狀陣列

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;
}