您的位置:首页 > 移动开发

POJ3321-Apple Tree(dfs序+线段树)

2018-02-11 19:54 309 查看
poj3321 原题链接:http://poj.org/problem?id=3321

Apple Tree
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 30871 Accepted: 9243
Description
There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow in the tree. Kaka likes apple very much, so he has been carefully nurturing the big apple tree.
The tree has N forks which are connected by branches. Kaka numbers the forks by 1 to N and the root is always numbered by 1. Apples will grow on the forks and two apple won't grow on the same fork. kaka wants to know how many apples are there in a sub-tree, for his study of the produce ability of the apple tree.
The trouble is that a new apple may grow on an empty fork some time and kaka may pick an apple from the tree for his dessert. Can you help kaka?



InputThe first line contains an integer N (N ≤ 100,000) , which is the number of the forks in the tree.
The following N - 1 lines each contain two integers u and v, which means fork u and fork v are connected by a branch.
The next line contains an integer M (M ≤ 100,000).
The following M lines each contain a message which is either
"C x" which means the existence of the apple on fork x has been changed. i.e. if there is an apple on the fork, then Kaka pick it; otherwise a new apple has grown on the empty fork.
or
"Q x" which means an inquiry for the number of apples in the sub-tree above the fork x, including the apple (if exists) on the fork x
Note the tree is full of apples at the beginning
OutputFor every inquiry, output the correspond answer per line.Sample Input3
1 2
1 3
3
Q 1
C 2
Q 1
Sample Output3
2
题目大意:
给出一个苹果树,每个节点一开始都有苹果,在给出几条边,连接节点C X,如果X点有苹果,则拿掉,如果没有,则新长出一个Q X,查询X点与它的所有后代分支一共有几个苹果
思路:刚拿到题目无从下手,xjb做然后tle了,百度后学到了很神奇的将树化为线性结构然后用线段树求解.1.用邻接表依题建树,我用的是数组实现的,详细内容写在我的另一篇博客里面http://blog.csdn.net/acm513828825/article/details/780560972.将每一个根节点用dfs遍历,进去的时间为这个点管理的左边界,出去的时间为这个点管理的右边界.
代码如下:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#include <vector>
#include <map>
#include <cstdlib>
#include <cstring>
#define ll long long
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define MAXN 100005
#define INF 1<<31
using namespace std;

vector <int> G[MAXN];
bool vis[MAXN];
int Sum,cnt,n,m,e[MAXN],q[MAXN],head[MAXN];

struct node{
int val,next;
}edge[MAXN<<1];

struct Tree{
int l,r;
int sum;
}tree[MAXN<<2];

void add_edge(int u,int v){
edge[cnt].val=v;
edge[cnt].next=head[u];
head[u]=cnt;
cnt++;
}

void dfs(int u){
++Sum;
q[u]=Sum;
vis[u]=true;
for(int i=head[u];i!=-1;i=edge[i].next){
if(vis[edge[i].val])    continue;
dfs(edge[i].val);
}
e[u]=Sum;
}

void pushup(int rt){
tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum;
}

void Build(int rt,int l,int r){
tree[rt].l=l;tree[rt].r=r;
if(l==r){
tree[rt].sum=1;
return;
}
int mid = (l+r)>>1;
Build(lson);
Build(rson);
pushup(rt);
}

void Modify(int rt,int x){
int l=tree[rt].l,r=tree[rt].r;
if(l==r){
if(tree[rt].sum){
tree[rt].sum=0;
return;
}
else
tree[rt].sum=1;
return;
}
int mid=(l+r)>>1;
if(x<=mid)
Modify(rt<<1,x);
else
Modify(rt<<1|1,x);
pushup(rt);
}

int Query(int rt,int l,int r){
if(tree[rt].l==l && tree[rt].r==r){
return tree[rt].sum;
}
int mid = (tree[rt].l+tree[rt].r)>>1;
if(r<=mid)
return Query(rt<<1,l,r);
else if(l>mid)
return Query(rt<<1|1,l,r);
else
return (Query(lson)+Query(rson));
}

int main()
{
while(scanf("%d",&n)!=EOF){
cnt=0;
int u,v;
for(int i=1;i<=n;i++){
head[i]=-1;
vis[i]=false;
}
for(int i=0;i<n-1;i++){
scanf("%d%d",&u,&v);
add_edge(u,v);

}
Sum = 0;
dfs(1);
Build(1,1,n);
char s[5];
int x;
scanf("%d",&m);
while(m--){
scanf("%s%d",s,&x);
if(s[0]=='C')
Modify(1,q[x]);
else
printf("q[%d]=%d e[%d]=%d\n",x,q[x],x,e[x]);
printf("%d\n",Query(1,q[x],e[x]));
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  dfs