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

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?

Input

The 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
"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
"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

Output

For every inquiry, output the correspond answer per line.

Sample Input

3
1 2
1 3
3
Q 1
C 2
Q 1

Sample Output

3
2

题目大意:

给出一个苹果树,每个节点一开始都有苹果,在给出几条边,连接节点
C X,如果X点有苹果,则拿掉,如果没有,则新长出一个
Q X,查询X点与它的所有后代分支一共有几个苹果


思路:
刚拿到题目无从下手,xjb做然后tle了,百度后学到了很神奇的将树化为线性结构然后用线段树求解.
1.用邻接表依题建树,我用的是数组实现的,详细内容写在我的另一篇博客里面http://blog.csdn.net/acm513828825/article/details/78056097
2.将每一个根节点用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;
}

猜你喜欢

转载自blog.csdn.net/acm513828825/article/details/79312915