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
  • 相关阅读:
    小批量随机梯度下降
    查询文档
    自动求梯度
    数据操作
    Hadoop 入门
    Matplotlib 二维图像绘制方法
    Pandas 数据处理基础
    NumPy 数值计算基础课程
    关于 Shell 脚本
    语法分析
  • 原文地址:https://www.cnblogs.com/whywhy/p/4655055.html
Copyright © 2011-2022 走看看