zoukankan      html  css  js  c++  java
  • [POI2010]KLO-Blocks(单调栈)

    题意

    给出N个正整数a[1..N],再给出一个正整数k,现在可以进行如下操作:每次选择一个大于k的正整数a[i],将a[i]减去1,选择a[i-1]或a[i+1]中的一个加上1。经过一定次数的操作后,问最大能够选出多长的一个连续子序列,使得这个子序列的每个数都不小于k。M组询问

    n<=1000000,m<=50;

    题解

    这题一开始想的是二分,但瞟了一眼范围觉得会T但是,觉得可以优化,所以就先写二分了。

    结果写挂了(不是T是WA了)然后优化也没来得及想就放弃了。(最后我也不知道怎么挂的,能不能用二分)


    我们把所有数减去k再求前缀和。

    所以就是求sum[i]-sum[j-1]>0且i-j最大

    假设我们已经确定了右端点,我们考虑两个左端点i,j。假设i<j且sum[i]<sum[j],那么j显然是没有用的。

    所以我们可以求出一个下标递增,sum递减的序列,用单调栈解决。

    然后我们从n到1枚举右端点。

    这个端点i对应的左端点j满足sum[i]>=sum[j]且j最小。

    然后我们一个一个弹栈,直到sum[j]>sum[i]此时最后一个被弹出栈的下标就是这个端点对应的答案。

    具体实现看代码

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<cmath>
     5 #include<algorithm>
     6 using namespace std;
     7 const long long N=1000100;
     8 long long n,a[N],m,k,b[N],sum[N],ans,top,stack[N];
     9 void work(){
    10     top=1;
    11     stack[1]=0;
    12     for(long long i=1;i<=n;i++){
    13         if(sum[i]<sum[stack[top]])stack[++top]=i;
    14     }
    15     stack[top+1]=n;
    16     for(long long i=n;i>=1;i--){
    17         while(top&&sum[stack[top]]<=sum[i]){
    18             top--;
    19         }
    20         ans=max(ans,i-stack[top+1]);
    21     } 
    22 }
    23 int main(){
    24     scanf("%lld%lld",&n,&m);
    25     for(long long i=1;i<=n;i++){
    26         scanf("%lld",&a[i]);
    27     }
    28     for(long long i=1;i<=m;i++){
    29     //    cout<<i<<"ashdfkjsdfhsd"<<endl;
    30         scanf("%lld",&k);
    31         ans=0;
    32         for(long long i=1;i<=n;i++){
    33             b[i]=a[i]-k;
    34             sum[i]=sum[i-1]+b[i];
    35         }
    36         work();
    37         printf("%lld ",ans);
    38     }
    39     return 0;
    40 }
  • 相关阅读:
    进程的两种开启方法,进程的常用方法,进程的常用属性
    并发编程简介
    周鸿祎:互联网成功十大案例
    sed用法详解
    awk与sed:一个关于多行处理的例子
    igmpproxy源代码学习——igmpProxyInit()
    获取网络接口信息——ioctl()函数与结构体struct ifreq、 struct ifconf
    unix网络编程——ioctl 函数的用法详解
    九大排序算法再总结
    浅谈《剑指offer》原题:不使用条件、循环语句求1+2+……+n
  • 原文地址:https://www.cnblogs.com/Xu-daxia/p/9444163.html
Copyright © 2011-2022 走看看