码迷,mamicode.com
首页 > 移动开发 > 详细

poj 3321Apple Tree

时间:2017-03-27 21:42:44      阅读:257      评论:0      收藏:0      [点我收藏+]

标签:str   sts   0ms   either   ges   names   ext   距离   message   

Apple Tree
Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u
Submit Status

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
/*
题意:给你一棵二叉树,root节点是1,初始的时候每个节点都有一个苹果,两种操作:
    C:x,对x节点的苹果数量进行异或
    Q:x,查询以x节点为根节点的子树的苹果的数量

初步思路:实际上就是建图,然后dfs跑一遍,记录下每个节点的左右区间,注意标记的时候将一个节点表示的区间内的点表示成连续的点,
    然后记录一下区间内点的区间长度,然后用树状数组进行区间求和单点更新

#超时:可能是初始化的时候超时
*/
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <vector>
using namespace std;
const int N=220000;
int n,m;
char str[10];
int Count=1;//用于表示重新标记的节点
int Start[N];//用于标记节点区间的开始位置
int End[N];//用于标记节点区间的结束位置
int lowbit[N];
int val[N];
int u,v;
int c[N];
typedef vector<int> VCT_INT;
vector<VCT_INT>edge(N/2);//用于构建图(树)
void dfs(int x){
    Start[x]=++Count;
    for(int i=0;i<edge[x].size();i++){
        dfs(edge[x][i]);
    }
    End[x]=++Count;
}
void add(int x,int val){
    while(x<=Count){
        c[x]+=val;
        x+=lowbit[x];
    }
}
int sum(int x){
    int res=0;
    while(x>0){
        res+=c[x];
        x-=lowbit[x];
    }
    return res;
}
int main(){
    // freopen("in.txt","r",stdin);
    scanf("%d",&n);
    for(int i=0;i<n-1;i++){
        scanf("%d%d",&u,&v);
        edge[u].push_back(v);//建图
    }
    Count=0;
    dfs(1);//从加点1开始搜索标记

    for(int i=1;i<=n;i++){
        val[i]=1;
    }
    //如果用add(i,1)的话会超时的,只能求出来每个的值,直接初始化
    // c[i]=i-(i-(lowbit(i)) );
    // 就是从1到i的苹果数减去距离i点最近的左侧的树上苹果的数量
    for(int i=1;i<=Count;i++){
        lowbit[i]=i&(i^(i-1));
    }
    for(int i=1;i<=Count;i++){
        c[i]=i-(i-lowbit[i]);
    }//初始状态下每个节点都有一个苹果
    scanf("%d",&m);
    for(int i=0;i<m;i++){
        scanf("%s%d",str,&u);
        if(str[0]==C){
            if(val[u]){
                add(Start[u],-1);
                add(End[u],-1);
                val[u]=0;
            }else{
                add(Start[u],1);
                add(End[u],1);
                val[u]=1;
            }
        }else{
            int x1=sum(End[u]);
            int x2=sum(Start[u]);
            printf("%d\n",(x1-x2)/2+val[u]);
        }
    }
    return 0;
}

 

poj 3321Apple Tree

标签:str   sts   0ms   either   ges   names   ext   距离   message   

原文地址:http://www.cnblogs.com/wuwangchuxin0924/p/6628593.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!