黑掉的一定是一个长度为$\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;
}