zoukankan      html  css  js  c++  java
  • (简单) POJ 3321 Apple Tree,树链剖分+树状数组。

    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?

      题目就是给一棵树,然后动态维护节点子树的值的和。

      本来很简单的一个题,只要dfs记录进入时间和出的时间就好,结果我傻逼的用树链剖分来做得,不过也简单,算是个裸题。

      不过忘了初始化树状数组WA了,%>_<%。。。

    代码如下:

    // ━━━━━━神兽出没━━━━━━
    //      ┏┓       ┏┓
    //     ┏┛┻━━━━━━━┛┻┓
    //     ┃           ┃
    //     ┃     ━     ┃
    //     ████━████   ┃
    //     ┃           ┃
    //     ┃    ┻      ┃
    //     ┃           ┃
    //     ┗━┓       ┏━┛
    //       ┃       ┃
    //       ┃       ┃
    //       ┃       ┗━━━┓
    //       ┃           ┣┓
    //       ┃           ┏┛
    //       ┗┓┓┏━━━━━┳┓┏┛
    //        ┃┫┫     ┃┫┫
    //        ┗┻┛     ┗┻┛
    //
    // ━━━━━━感觉萌萌哒━━━━━━
    
    // Author        : WhyWhy
    // Created Time  : 2015年07月17日 星期五 15时35分58秒
    // File Name     : 3321.cpp
    
    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <math.h>
    #include <stdlib.h>
    #include <time.h>
    
    using namespace std;
    
    const int MaxN=100005;
    
    struct Edge
    {
        int to,next;
    };
    
    Edge E[MaxN<<1];
    int head[MaxN],Ecou;
    
    int fa[MaxN],son[MaxN],siz[MaxN],dep[MaxN],top[MaxN],w[MaxN];
    int Tcou;
    
    int C[MaxN];
    
    void init()
    {
        Tcou=1;
        Ecou=0;
        w[1]=1;
        top[1]=1;
    
        memset(head,-1,sizeof(head));
        memset(C,0,sizeof(C));
    }
    
    void addEdge(int u,int v)
    {
        E[Ecou].to=v;
        E[Ecou].next=head[u];
        head[u]=Ecou++;
    }
    
    void dfs1(int u,int pre,int d)
    {
        int v;
    
        dep[u]=d;
        fa[u]=pre;
        siz[u]=1;
        son[u]=-1;
    
        for(int i=head[u];i!=-1;i=E[i].next)
            if(E[i].to!=pre)
            {
                v=E[i].to;
                dfs1(v,u,d+1);
                siz[u]+=siz[v];
    
                if(son[u]==-1 || siz[son[u]]<siz[v])
                    son[u]=v;
            }
    }
    
    void dfs2(int u)
    {
        if(son[u]==-1)
            return;
    
        top[son[u]]=top[u];
        w[son[u]]=++Tcou;
    
        dfs2(son[u]);
    
        int v;
    
        for(int i=head[u];i!=-1;i=E[i].next)
            if(E[i].to!=son[u] && E[i].to!=fa[u])
            {
                v=E[i].to;
                top[v]=v;
                w[v]=++Tcou;
                dfs2(v);
            }
    }
    
    int N;
    
    inline int lowbit(int x)
    {
        return x&(-x);
    }
    
    void add(int x,int d)
    {
        while(x<=N)
        {
            C[x]+=d;
            x+=lowbit(x);
        }
    }
    
    int sum(int x)
    {
        int ret=0;
    
        while(x>0)
        {
            ret+=C[x];
            x-=lowbit(x);
        }
    
        return ret;
    }
    
    void update(int u,int v,int d)
    {
        int f1=top[u],f2=top[v];
    
        while(f1!=f2)
        {
            if(dep[f1]<dep[f2])
            {
                swap(f1,f2);
                swap(u,v);
            }
    
            add(w[f1],d);
            add(w[u]+1,-d);
            u=fa[f1];
            f1=top[u];
        }
    
        if(dep[u]>dep[v])
            swap(u,v);
    
        add(w[u],d);
        add(w[v]+1,-d);
    }
    
    bool rem[MaxN];
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        //freopen("out.txt","w",stdout);
    
        int M;
        int a,b;
        char s[10];
    
        while(~scanf("%d",&N))
        {
            init();
            memset(rem,0,sizeof(rem));
    
            for(int i=1;i<N;++i)
            {
                scanf("%d %d",&a,&b);
                addEdge(a,b);
                addEdge(b,a);
            }
    
            dfs1(1,-1,1);
            dfs2(1);
    
            scanf("%d",&M);
    
            for(int i=1;i<=N;++i)
                update(1,i,1);
    
            while(M--)
            {
                scanf("%s %d",s,&a);
    
                if(s[0]=='Q')
                    printf("%d
    ",sum(w[a]));
                else
                {
                    update(1,a,rem[a]?1:-1);
                    rem[a]=!rem[a];
                }
            }
        }
        
        return 0;
    }
    View Code
  • 相关阅读:
    学习Python中的集合
    ubuntu14.04下 安装matlabR2015b遇到的一些问题及其解决方法
    matlab的一些关于块分类的函数~~~
    20145207 《Java程序设计》第二周学习总结
    20145207 调查问卷
    20145207 《Java程序设计》第一周学习总结
    10、装饰者模式
    9、观察者模式
    8、迭代器模式
    7、适配器模式
  • 原文地址:https://www.cnblogs.com/whywhy/p/4655055.html
Copyright © 2011-2022 走看看