POJ 3321Apple Tree(dfs序 树状数组)

来源:互联网 发布:ruby for windows 编辑:程序博客网 时间:2024/06/06 03:17

传送门:http://poj.org/problem?id=3321
刚开始看到这题的时候,直接敲了一发模拟准备水过,结果TLE了,仔细想想确实是会超时的,如果变成一条直线的话,修改操作的复杂度就是O(N),妥妥超时。想了半天不知道怎么做,后来一查发现是树状数组,一时间没想出来怎么做,因为原来做的树状数组都是一条直线上操作,不知道怎么在树上建立树状数组。学习了一发别人的博客,才知道还有一种思路是根据树的dfs序来建立树状数组,先dfs一下,然后在dfs的时候编号。那么一个节点和他的全部子树的编号一定是连续的。所以这段连续区间就可以用来表示这个节点和他的子树。第一次看到这种做法,感觉非常吊炸天。

#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <cstdlib>#include <cctype>#include <string>#include <iostream>#include <vector>#include <map>#include <queue>#include <ctime>using namespace std;typedef long long ll;typedef pair<int,int> pii;#define PB push_back#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define calm (l+r)>>1const int INF=1e9+7;const int maxn=100100;struct EE{    int to,next;    EE(){}    EE(int to,int next):to(to),next(next){}}edge[maxn];int n,m,head[maxn],Ecnt,vis;int st[maxn],ed[maxn],v[maxn];int tree[maxn]={0};inline void add(int s,int t){    edge[Ecnt]=EE(t,head[s]);    head[s]=Ecnt++;}void update(int x,int v){    while(x<=n){        tree[x]+=v;        x+=x&(-x);    }}int sum(int x){    int ans=0;    while(x){        ans+=tree[x];        x-=x&(-x);    }    return ans;}void build(int s){    st[s]=++vis;//st[s]表示当前这个节点    for(int i=head[s];~i;i=edge[i].next){        build(edge[i].to);    }    ed[s]=vis;//ed[x]表示它的所有子树的编号的最后一个,st[s]--ed[s]这段区间就可以表示这个节点与它的所有子树}int main(){    #ifdef LOCAL        freopen("input.txt","r",stdin);    #endif    scanf("%d",&n);    memset(head,-1,sizeof head);Ecnt=0;    for(int i=1;i<n;i++){        int a,b;scanf("%d%d",&a,&b);        add(a,b);    }    vis=0;    build(1);    for(int i=1;i<=n;i++){        v[i]=1;update(st[i],1);        //printf("%d %d\n",st[i],ed[i]);    }    scanf("%d",&m);    while(m--){        char op[2];        scanf("%s",op);        if(op[0]=='Q'){            int x;scanf("%d",&x);            printf("%d\n",sum(ed[x])-sum(st[x]-1));        }        else{            int x;scanf("%d",&x);            if(v[x]==1){                    update(st[x],-1);            }            else{                update(st[x],1);            }            v[x]=1-v[x];        }    }    #ifdef LOCAL        printf("[Run in %.1fs]\n",(double)clock()/CLOCKS_PER_SEC);    #endif    return 0;}
0 0
原创粉丝点击