BZOJ4123 : [Baltic2015]Hacker

黑掉的一定是一个长度为$\lfloor\frac{n+1}{2}\rfloor$的区间。

于是枚举初始点,然后查询包含它的区间的最小值。

通过维护前后缀最小值+单调队列$O(n)$解决。

 

#include<cstdio>
#define N 500010
int n,k,i,a[N<<1],s[N],pre[N],suf[N],q[N],h,t,ans;
inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
inline void max(int b){if(ans<b)ans=b;}
inline int min(int a,int b){return a<b?a:b;}
int main(){
  read(n);k=(n+1)/2-1;
  for(i=1;i<=n;i++)read(a[i]),a[i+n]=a[i];
  for(i=2;i<=n*2;i++)a[i]+=a[i-1];
  for(i=1;i<=n;i++)s[i]=a[i+k]-a[i-1];
  for(pre[0]=s[i=1];i<=n;i++)pre[i]=min(pre[i-1],s[i]);
  for(suf[n+1]=s[i=n];i;i--)suf[i]=min(suf[i+1],s[i]);
  for(h=i=1;i<=k;q[++t]=i++){
    max(min(pre[i],suf[i+n-k]));
    while(h<=t&&s[q[t]]>=s[i])t--;
  }
  for(;i<=n;i++){
    while(h<=t&&s[q[t]]>=s[i])t--;q[++t]=i;
    while(i-q[h]>k)h++;
    max(s[q[h]]);
  }
  return printf("%d",ans),0;
}

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值