zoukankan      html  css  js  c++  java
  • poj3321

    Codevs中文版评测地址:http://codevs.cn/problem/1228/
    Apple Tree
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 26382   Accepted: 7832

    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
    

    Source

    POJ Monthly--2007.08.05, Huang, Jinsong
     

    题意:一颗有n个分支的苹果树,根为1,每个分支只有一个苹果,给出n-1个分支的关系和给出m个操作,Q x表示询问x的子树(包括x)苹果的数量,C x表示若分支x上有苹果,则摘下来,若没有则会生出一个,输出每个询问的值。

    分析:每个分支其实就是一个节点,先dfs先序遍历整个树,求出每个节点的时间戳,即每个节点第一次访问的时间和最后一次访问的时间,分别用li和ri记录,以时间戳为编号,则在li[x]和ri[x]之间的编号的节点就是x的子树,以时间戳为树状数组的下标,查询时,只要求第一次访问的编号到最后一次访问的编号之间的和就行了,即sum(ri[x])-sum(li[x]-1);修改时,只要修改第一次访问的编号即可,即update(li[x])。但是修改前要判断该位置是0或1,0则加1,1则减1。

    当然也可以用线段树实现,今天想练练树状数组,so就用树状数组写了。

    AC代码:

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define N 100010
    inline const int read(){
        register int x=0,f=1;
        register char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    inline const char in(){
        for(register char ch=getchar();;ch=getchar()) if(ch>='A'&&ch<='Z') return ch;
    }
    struct node{
        int v,next;
    }e[N];
    int n,m,cnt,tot,head[N];
    int li[N],ri[N],c[N];
    void add(int x,int y){
        e[++cnt].v=y;
        e[cnt].next=head[x];
        head[x]=cnt;
    }
    void dfs(int x){
        li[x]=++tot;
        for(int i=head[x];i;i=e[i].next) dfs(e[i].v);
        ri[x]=tot;
    }
    int lowbit(int x){
        return x&-x;
    }
    void updata(int p,int v){
        for(int i=p;i<=n;i+=lowbit(i)) c[i]+=v;
    }
    int query(int p){
        int res=0;
        for(int i=p;i;i-=lowbit(i)) res+=c[i];
        return res;
    }
    int main(){
        n=read();
        for(int i=1,x,y;i<n;i++) x=read(),y=read(),add(x,y);
        dfs(1);
        for(int i=1;i<=n;i++) updata(i,1);
        m=read();char ch;
        for(int i=1,x;i<=m;i++){
            if((ch=in())=='C'){
                x=read();
                if(query(li[x])-query(li[x]-1))
                    updata(li[x],-1);
                else
                    updata(li[x],1);
            }
            else{
                x=read();
                printf("%d
    ",query(ri[x])-query(li[x]-1));
            }
        }
        return 0;
    }
  • 相关阅读:
    使用 star UML制作的图
    评价片段
    项目部分
    用新学的知识 写了一段小代码
    常用系统存储过程
    考试小总结
    分页
    行转列面试题 事例
    子查询
    生成验证码的方法集合(一)
  • 原文地址:https://www.cnblogs.com/shenben/p/5764932.html
Copyright © 2011-2022 走看看