zoukankan      html  css  js  c++  java
  • Problem A. Array Factory XVII Open Cup named after E.V. Pankratiev Stage 4: Grand Prix of SPb, Sunday, Octorber 9, 2016

    思路:

      直接二分长度不可行,因为有负数。

      考虑枚举坐便删l个数,那如果可以在短时间内求出符合条件的右边最小删的数的个数,这题便可做了。

      即:当左边删l个数时,要使sum[n]-sum[l]-fsum[n+1-x] <= s成立,求出最小的x。(sum为前缀和,fsum为后缀和)

      思考后可以发现可行的fsum[x]必然要是正数,可能的答案x必然是单调递增的(x从0开始)。

      所以维护一个大于0的递增的单调栈即可,在里面二分找答案。

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 #define MP make_pair
     6 #define PB push_back
     7 typedef long long LL;
     8 typedef pair<int,int> PII;
     9 const double eps=1e-8;
    10 const double pi=acos(-1.0);
    11 const int K=1e6+7;
    12 const LL mod=1e9;
    13 
    14 int n,cnt,tot,ans=K,nl,id[K];
    15 LL s,tmp,sum[K],q[K];
    16 
    17 void check(int x)
    18 {
    19     int ta=lower_bound(q,q+tot+1,sum[n]-sum[x]-s)-q;
    20     if(sum[n]-sum[x]-q[ta]<=s && x+n-id[ta]+1 < ans)
    21         ans=x+n-id[ta]+1,nl=x;
    22 }
    23 int main(void)
    24 {
    25     cin>>n>>s;
    26     id[0]=n+1;
    27     for(int i=1,x;i<=n;i++) scanf("%d",&x),sum[i]+=sum[i-1]+x;
    28     for(int i=n;i;i--)
    29     {
    30         tmp+=sum[i]-sum[i-1];
    31         if(tmp>q[tot])
    32             q[++tot]=tmp,id[tot]=i;
    33     }
    34     for(int i=0;i<=n;i++)
    35     {
    36         if(id[tot]==i)  tot--;
    37         check(i);
    38     }
    39     if(ans>=n)
    40         printf("-1
    ");
    41     else
    42         printf("%d
    %d %d
    ",n-ans,nl,ans-nl);
    43     return 0;
    44 }
  • 相关阅读:
    ID的插入
    开发语言的选择
    象数据库一样连接EXCEL
    前端,你真的了解JavaScript吗?
    开源软件与自由软件
    在codeigniter中使用Cache_Lite来缓存
    使用Codeigniter的SMTP类发Email
    JavaScript变量和数据类型
    JavaScript的隐式声明和变量声明提升的总结
    ASCII和UNICODE编码以及UTF8,你懂的?
  • 原文地址:https://www.cnblogs.com/weeping/p/7608755.html
Copyright © 2011-2022 走看看