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
  • 相关阅读:
    上传图片,语音,和富文本(webuploader,dropzone, froala)
    java代码备份mysql数据库
    maven 父子工程打包 并且上传linux服务器
    docker+fastdfs+nginx 实现分布式大文件存储系统以及视频缓存播放
    docker eureka 注册中心 服务提供者通信机制
    lvs dr 模型配置详解
    spring cloud 详解
    JS前端创建CSV或Excel文件并浏览器导出下载
    修改ElementUI源码实践
    Leaflet+heatmap实现离线地图加载和热力图应用
  • 原文地址:https://www.cnblogs.com/whywhy/p/4655055.html
Copyright © 2011-2022 走看看