zoukankan      html  css  js  c++  java
  • [POI2012]STU-Well(二分答案+神仙操作)

    给定一个非负整数序列A,每次操作可以选择一个数然后减掉1,要求进行不超过m次操作使得存在一个Ak=0且max{|Ai−Ai+1|}最小,输出这个最小lk以及最小值。

    Solution

    最大值最小,显然是需要二分的,而且我们发现答案确实是有单调性的。

    接下来我们正着扫一遍整个序列,把差值大于二分出来的值的数调整值合法。

    接下来我们就要考虑ak=0的情况,这个东西并没有什么单调性,我们只能从头枚举,直到找到第一个满足要求的就可以了。

    考虑当一个数变成零之后,为了满足我们二分出来的答案,我们需要构造这样一个东西。

    0                      0

    0 0                0 0

    0 0 0          0 0 0

    0 0 0 0    0 0 0 0

    0 0 0 0 0 0 0 0 0

    两边是等差数列,为了计算序列的长度,我们需要计算出两个数组表示当ai=0是等差数列的左端点和右端点。

    我们可以把左右分开算。

    比如计算右端点,我们从i向右暴力扩展,当发现当前数字的值小于目标值是就不再扩展了,因为后面已经符合要求了。

    最后枚举点,用等差数列求和算一下就可以了。

    Code

    #include<iostream>
    #include<cstdio>
    #define N 1000002
    using namespace std;
    typedef long long ll;
    ll ans2,ans,b[N],s1[N],le[N],ri[N],a[N],n,m,sum[N];
    bool check(ll pos){
        ll num=0;
        for(int i=1;i<=n;++i)b[i]=a[i];
        for(int i=2;i<=n;++i)
          if(b[i]-b[i-1]>pos)num+=b[i]-b[i-1]-pos,b[i]=b[i-1]+pos;
        if(num>m)return 0;
        for(int i=n-1;i>=1;--i)
          if(b[i]-b[i+1]>pos)num+=b[i]-b[i+1]-pos,b[i]=b[i+1]+pos;
        if(num>m)return 0;
        for(int i=1;i<=n;++i)sum[i]=sum[i-1]+b[i];
        for(int i=1,j=1;i<=n;++i){
             while(b[j]<=(i-j)*pos&&j<i)j++;
             le[i]=j;
        }
        for(int i=n,j=n;i>=1;--i){
            while(b[j]<=(j-i)*pos&&j>i)j--;
             ri[i]=j;
        }
        for(int i=1;i<=n;++i)
             if((num+sum[ri[i]]-sum[le[i]-1]-pos*((i-le[i])*(i-le[i]+1)+(ri[i]-i)*(ri[i]-i+1))/2)<=m)
             {ans=i;return 1;} 
        return 0;
    }
    int main(){
        scanf("%lld%lld",&n,&m);    
        ll l=0,r=1e9;
        for(int i=1;i<=n;++i)scanf("%lld",&a[i]);
        while(l<=r){
            int mid=(l+r)>>1;
            if(check(mid)){
                ans2=mid;
                r=mid-1;
            }
            else l=mid+1;
        }
        printf("%lld %lld",ans,ans2);
        return 0; 
    } 
  • 相关阅读:
    二维码在短信业务应用的初步构思
    Twproject Gantt开源甘特图功能扩展
    vscode 1.5安装体验
    OpenLiveWriter代码插件
    golang语言构造函数
    WebAPI接口返回ArrayList包含Dictionary对象正确解析
    golang枚举类型
    Gatekeeper Pattern 把关(守门人)模式
    .NET Core Windows环境安装与体验
    Federated Identity Pattern 联合身份模式
  • 原文地址:https://www.cnblogs.com/ZH-comld/p/9677644.html
Copyright © 2011-2022 走看看