POJ 3321-Apple Tree(DFS序+树状数组)

来源:互联网 发布:wps for mac 编辑:程序博客网 时间:2024/06/06 03:36

题目链接:http://poj.org/problem?id=3321


大致题意:给你一棵树,有n个点,每个点初始时权值为1,有两种操作:

(1)C x :若节点x的权值为1,则将其变为0,否则将其变为1

(2)Q x :查询点x的所有子节点(包括x)的权值和


dfs序模板题,巧妙的利用dfs序的性质

DFS序: 就是DFS整棵树依次访问到的结点组成的序列


DFS序性质: 一颗子树的所有节点在DFS序内是连续的一段


剩下的就是区间求和问题了,用树状数组随便搞搞

这题还有个坑点是建边是单纯的vector会超时,需要建双重容器Orz(重要的是这题的方法,没去深究)


#include<map>#include<stack>#include<queue>#include<vector>#include<math.h>#include<stdio.h>#include<iostream>#include<string.h>#include<stdlib.h>#include<algorithm>using namespace std;typedef long long  ll;#define inf 10000000#define mod 1000000007 #define  maxn  200005#define  lowbit(x) (x&-x)#define  eps 1e-10int n,vis[maxn],ed[maxn],st[maxn],s[maxn],cnt;vector<vector<int> > q(maxn);void dfs(int x)//求dfs序{st[x]=cnt;for(int i=0;i<q[x].size();i++){cnt++;dfs(q[x][i]);}ed[x]=cnt;}void add(int x,int y){while(x<=n){s[x]+=y;x+=lowbit(x);}}int sum(int x){int res=0;while(x>0){res+=s[x];x-=lowbit(x);}return res;}int main(void){char c[5];int i,j,x,y,m;while(~scanf("%d",&n)){memset(s,0,sizeof(s));memset(st,0,sizeof(st));memset(ed,0,sizeof(ed));memset(vis,0,sizeof(vis));for(i=0;i<maxn;i++)q[i].clear();for(i=1;i<n;i++){scanf("%d%d",&x,&y);q[x].push_back(y);}for(i=1;i<=n;i++)  add(i,1);  cnt=1;dfs(1);scanf("%d",&m);while(m--){scanf("%s%d",c,&x);if(c[0]=='Q')printf("%d\n",sum(ed[x])-sum(st[x]-1));else{if(vis[x])add(st[x],1);elseadd(st[x],-1);vis[x]=1-vis[x];}}}return 0;}




原创粉丝点击