POJ 3321 树状数组+DFS

来源:互联网 发布:highcharts.js api 编辑:程序博客网 时间:2024/05/16 15:52

题意

给一棵树,输入C和一个点的话,如果这个点上原来有苹果的话,则这个点将会变成没有苹果的点。如果这个点上原来没有苹果的话,则这个点将会变成有苹果的点。如果输入Q的话,则代表进行查询操作,查询操作是查询某个点及其子树的苹果总和。

题解

树状数组+DFS序。这个就和线段树是一样的。首先的话,DFS序给所有点编号。点更新的话,直接单点更新就可以了。查询的话,找到查询点的起始和终止编号,利用树状数组进行区间查询就可以了。

代码

#include <iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<vector>#include<cmath>#include<queue>#include<string>#include<set>#include<map>#include<bitset>#include<stack>#include<string>#define UP(i,l,h) for(int i=l;i<h;i++)#define DOWN(i,h,l) for(int i=h-1;i>=l;i--)#define W(a) while(a)#define MEM(a,b) memset(a,b,sizeof(a))#define LL long long#define INF 0x3f3f3f3f#define MAXN 800010#define MOD 1000000009#define EPS 1e-10using namespace std;int head[100015],nex[100015];int deep;bool vis[100015];int st[100015],ed[100015],num[100015];int n,m;void dfs(int u,int p) {    st[u]=deep++;    for(int xx=head[u];xx!=-1;xx=nex[xx]){        if(xx==p)            continue;        dfs(xx,u);    }    ed[u]=deep-1;}int lowbit(int x) {    return x&(-x);}void add(int x,int d) {    for(int i=x; i<=n+10; i+=lowbit(i)) {//        cout<<i<<endl;        num[i]+=d;    }}int query(int x) {    int sum=0;    for(int i=x; i>0; i-=lowbit(i)) {        sum+=num[i];    }    return sum;}int main() {    W(~scanf("%d",&n)) {        MEM(num,0);        MEM(st,0);        MEM(ed,0);        MEM(vis,false);        MEM(head,-1);        MEM(nex,-1);        int a,b;        UP(i,0,n-1) {            scanf("%d%d",&a,&b);//            nodes[a].push_back(b);            nex[b]=head[a];            head[a]=b;        }        deep=1;        dfs(1,0);        UP(i,1,deep){            add(i+1,1);            vis[i]=true;        }//        cout<<"dfs"<<endl;        scanf("%d",&m);        char c[5];        UP(i,0,m) {            getchar();            scanf("%s%d",&c,&a);            if(strcmp(c,"Q")==0) {                int s=st[a];                int e=ed[a];                printf("%d\n",query(e+1)-query(s));            } else {                if(!vis[st[a]]) {//                        cout<<st[a]<<endl;                    add(st[a]+1,1);                    vis[st[a]]=true;                } else {                    add(st[a]+1,-1);                    vis[st[a]]=false;                }            }        }    }}