• cf 1208E


    给定n个序列,每个一行,每个序列是可以左右移动的,对于每行可以随意移动的情况下,求每列的和的最大值

    n行(1<=n<=10^6) ,w列(1<=w<=10^6)

    题解:

    首先由于左右边界的限制,最大为w,所以对于每行,可以填进一个列中的数是被限制的。所以我们要找到在这些可选的数中的最大值。因为这些可选的数都是连续的,并且要找最大值,可以想到用ST表查找区间最大值。

    对于每个序列分成两种情况:

    1.序列长度小于w的一半,这种情况是有某些处于中间的列可以选择所有输入序列的数,开头/结尾的k个直接维护前k个的最大值。影响进行差分处理。

    2.长度大于等于w的一半,直接st表求出最大值即可,使用差分维护。

    #include <bits/stdc++.h>
    using namespace std;
    #define  ll long long
    int n,w,m,lg[1000100],st[2000100][23];
    ll ans[1000100];
    inline int query(int l,int r)
    {
        int k=lg[r-l+1];
        return max(st[l][k],st[r-(1<<k)+1][k]);
    }
    int main()
    {
        int i,j,k;
        scanf("%d%d",&n,&w);
        for(i=2;i<=1000000;i++)lg[i]=lg[i>>1]+1;
        for(int kk=1;kk<=n;kk++)
        {
            scanf("%d",&m);
            for(i=1;i<=m;i++)scanf("%d",&st[i][0]);
            for(i=1;i<=20;i++)
                for(j=1;j<=m;j++)
                    st[j][i]=max(st[j][i-1],st[j+(1<<(i-1))][i-1]);
             if(2*m>=w)//第二种情况
             {
                 for(i=1;i<=w;i++)
                 {
                     int l=m-w+i,r=i,v=query(max(l,1),min(r,m));
                     if(l<1||r>m)v=max(v,0);//可以有不选的情况(即靠近端点处的特殊情况)
                     ans[i]+=(ll)v;
                     ans[i+1]-=(ll)v;
                 }
             } else {
                 int v1 = 0, v2 = 0;
                 for (i = 1; i <= m; i++)
                 {
                     v1 = max(v1, st[i][0]);
                     v2 = max(v2, st[m - i + 1][0]);
                     ans[i] += (ll) v1;
                     ans[i + 1] -= (ll) v1;
                     ans[w - i + 1] += (ll) v2;
                     ans[w - i + 2] -= (ll) v2;
                 }
                 ans[m + 1] += (ll) v1;
                 ans[w - m + 1] -= (ll) v1;
             }
        }
        for(i=1;i<=w;i++)
        {
            ans[i]+=ans[i-1];
            printf("%lld ",ans[i]);
        }
        puts("");
        return 0;
    }
    
  • 相关阅读:
    终结篇:MyBatis原理深入解析(二)
    Centos7 安装clamav杀毒
    jenkins 自动化部署
    docker 安装redis
    linux CentOS7 安装字体库-转
    docker 安装jenkins
    linux 下安装docker
    linux 下安装redis
    linux 下mongo 基础配置
    Linux下MongoDB安装和配置详解
  • 原文地址:https://www.cnblogs.com/nuchenghao/p/11425661.html
Copyright © 2020-2023  润新知