zoukankan      html  css  js  c++  java
  • 洛谷 P4556 [Vani有约会]雨天的尾巴 解题报告

    P4556 [Vani有约会]雨天的尾巴

    题目背景

    深绘里一直很讨厌雨天。
    灼热的天气穿透了前半个夏天,后来一场大雨和随之而来的洪水,浇灭了一切。
    虽然深绘里家乡的小村落对洪水有着顽固的抵抗力,但也倒了几座老房子,几棵老树被连根拔起,以及田地里的粮食被弄得一片狼藉。
    无奈的深绘里和村民们只好等待救济粮来维生。
    不过救济粮的发放方式很特别。

    题目描述

    首先村落里的一共有(n)座房屋,并形成一个树状结构。然后救济粮分(m)次发放,每次选择两个房屋((x,y)),然后对于(x)(y)的路径上(含(x)(y))每座房子里发放一袋(z)类型的救济粮。
    然后深绘里想知道,当所有的救济粮发放完毕后,每座房子里存放的最多的是哪种救济粮。

    输入输出格式

    输入格式:

    第一行两个正整数(n),(m),含义如题目所示。
    接下来(n-1)行,每行两个数((a,b)),表示((a,b))间有一条边。
    再接下来(m)行,每行三个数((x,y,z)),含义如题目所示。

    输出格式:

    (n)行,第(i)行一个整数,表示第(i)座房屋里存放的最多的是哪种救济粮,如果有多种救济粮存放次数一样,输出编号最小的。
    如果某座房屋里没有救济粮,则对应一行输出(0)

    说明

    对于(20\%)的数据,(1 <= n, m <= 100)
    对于(50\%)的数据,(1 <= n, m <= 2000)
    对于(100\%)的数据,(1 <= n, m <= 100000, 1 <= a, b, x, y <= n, 1 <= z <= 100000)


    线段树合并+差分。

    头有点疼,一直写挂。

    挂一下错误。

    倍增( t{LCA})(dep)数组没有置(dep[1]=1)

    ( t{Merge})时偷懒想省空间,写了个

    if(!mx[now]||!mx[las]) return now+las;
    

    恩,因为有(-1),所以错了、、


    Code:

    #include <cstdio>
    const int N=1e5+10;
    int Next[N<<1],to[N<<1],head[N],cnt;
    void add(int u,int v)
    {
        to[++cnt]=v,Next[cnt]=head[u],head[u]=cnt;
    }
    int f[N][20],dep[N],n,m;
    void dfs0(int now)
    {
        for(int i=1;f[now][i-1];i++) f[now][i]=f[f[now][i-1]][i-1];
        for(int i=head[now];i;i=Next[i])
        {
            int v=to[i];
            if(v!=f[now][0])
            {
                dep[v]=dep[now]+1;
                f[v][0]=now;
                dfs0(v);
            }
        }
    }
    void swap(int &x,int &y){int tmp=x;x=y,y=tmp;}
    int LCA(int u,int v)
    {
        if(dep[u]<dep[v]) swap(u,v);
        for(int i=18;~i;i--)
            if(dep[f[u][i]]>=dep[v])
                u=f[u][i];
        if(u==v) return u;
        for(int i=18;~i;i--)
            if(f[u][i]!=f[v][i])
                u=f[u][i],v=f[v][i];
        return f[u][0];
    }
    int mx[N*50],id[N*50],ch[N*50][2],ans[N],root[N],tot;
    #define ls ch[now][0]
    #define rs ch[now][1]
    #define ols ch[las][0]
    #define ors ch[las][1]
    void updata(int now)
    {
        if(mx[ls]>=mx[rs])
            mx[now]=mx[ls],id[now]=id[ls];
        else
            mx[now]=mx[rs],id[now]=id[rs];
    }
    void change(int &now,int l,int r,int p,int d)
    {
        if(!now) now=++tot;
        if(l==r)
        {
            mx[now]+=d,id[now]=l;
            return;
        }
        int mid=l+r>>1;
        if(p<=mid) change(ls,l,mid,p,d);
        else change(rs,mid+1,r,p,d);
        updata(now);
    }
    int Merge(int now,int las,int l,int r)
    {
        if(!now||!las) return now+las;
        if(l==r) return id[now]=l,mx[now]+=mx[las],now;
        int mid=l+r>>1;
        ls=Merge(ls,ols,l,mid),rs=Merge(rs,ors,mid+1,r);
        updata(now);
        return now;
    }
    void dfs(int now)
    {
        for(int i=head[now];i;i=Next[i])
        {
            int v=to[i];
            if(v!=f[now][0])
            {
                dfs(v);
                root[now]=Merge(root[now],root[v],1,n);
            }
        }
        ans[now]=mx[root[now]]?id[root[now]]:0;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int u,v,i=1;i<n;i++) scanf("%d%d",&u,&v),add(u,v),add(v,u);
        dep[1]=1;
        dfs0(1);
        int n0=n;n=N-10;
        for(int u,v,w,lca,i=1;i<=m;i++)
        {
            scanf("%d%d%d",&u,&v,&w);
            lca=LCA(u,v);
            change(root[u],1,n,w,1);
            change(root[v],1,n,w,1);
            change(root[lca],1,n,w,-1);
            change(root[f[lca][0]],1,n,w,-1);
        }
        dfs(1);
        for(int i=1;i<=n0;i++) printf("%d
    ",ans[i]);
        return 0;
    }
    

    2018.11.1

  • 相关阅读:
    node
    github
    [模块] pdf转图片-pdf2image
    python 15 自定义模块 随机数 时间模块
    python 14 装饰器
    python 13 内置函数II 匿名函数 闭包
    python 12 生成器 列表推导式 内置函数I
    python 11 函数名 迭代器
    python 10 形参角度 名称空间 加载顺序
    python 09 函数参数初识
  • 原文地址:https://www.cnblogs.com/butterflydew/p/9891400.html
Copyright © 2011-2022 走看看