题目:
给你一个$n$和一个长度为$n$的序列。
对于序列的前$lceilfrac{n}{2} ceil$项,第$i$项的值为$a_i$,对于序列的后面所有项,值均为$x$。
你需要给出一个$k$,使得任意一个长度为$k$的子区间的和都$>0$,若有多解,输出任意一个,如果不存在这样的$k$,输出$-1$。
直接给出结论:当$xgeq0$是,选出整段是最优的,直接检验长度为$n$的区间是否可行。
而对于$x<0$的情况,答案的区间长度一定大于后$n-lceilfrac{n}{2} ceil$项。
设$temp$为当前从大到小枚举到的区间长度,可以用线段树维护区间和最小值。
当前区间个数为$n-temp+1$:
如果这些区间和最小值$>0$,就找到了一个满足要求的区间长度;
反之,区间长度$++$,满足区间长度的区间个数$--$,去掉最末尾的一个区间。
#include <bits/stdc++.h> using namespace std; inline int read() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();} while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x*f; } typedef long long ll; const int maxn=5e5+5; int n,a[maxn],x; ll sum[maxn],b[maxn]; struct Node{ ll Min,lazy; }tree[maxn<<2]; void pushup(int rt) { tree[rt].Min=min(tree[rt<<1].Min,tree[rt<<1|1].Min); } void build(int rt,int l,int r) { if(l==r) { tree[rt].Min=b[l]; return; } int mid=l+r>>1; build(rt<<1,l,mid); build(rt<<1|1,mid+1,r); pushup(rt); } void pushdown(int rt) { if(tree[rt].lazy) { ll x=tree[rt].lazy;tree[rt].lazy=0; tree[rt<<1].Min+=x,tree[rt<<1|1].Min+=x; tree[rt<<1].lazy+=x,tree[rt<<1|1].lazy+=x; } } void update(int rt,int l,int r,int L,int R,ll x) { if(L>R) return; if(L<=l&&R>=r) { tree[rt].Min+=x; tree[rt].lazy+=x; return; } pushdown(rt); int mid=l+r>>1; if(L<=mid) update(rt<<1,l,mid,L,R,x); if(R>mid) update(rt<<1|1,mid+1,r,L,R,x); pushup(rt); } ll query(int rt,int l,int r,int L,int R) { if(L<=l&&R>=r) return tree[rt].Min; pushdown(rt); int mid=l+r>>1; ll res=1e18; if(L<=mid) res=query(rt<<1,l,mid,L,R); if(R>mid) res=min(res,query(rt<<1|1,mid+1,r,L,R)); pushup(rt); return res; } int main() { n=read(); for(int i=1;i<=(n+1)/2;++i) a[i]=read(); x=read(); for(int i=(n+1)/2+1;i<=n;++i) a[i]=x; for(int i=1;i<=n;++i) sum[i]=sum[i-1]+a[i]; if(x>=0) { if(sum[n]>0) printf("%d ",n); else puts("-1"); } else { int len=n-(n+1)/2+1;n=(n+1)/2; for(int i=1;i<=n;++i) b[i]=sum[i+len-1]-sum[i-1]; build(1,1,n); int temp=n; while(temp) { if(query(1,1,n,1,temp)<=0) { temp--,len++; update(1,1,n,1,temp,x); } else printf("%d ",len),exit(0); } puts("-1"); } return 0; }