【分析】首先,求的是子串和,想到前缀和,然后求的是子串和>0时候的最小和;就是sum[i]-sum[j] > 0(j < i)下的min{sum[i]-sum[j]};
而这就是求sum[i]>sum[j]时sum[j]的最大值,那么离散一下所有sum,从左往右扫描,对于每个sum[i]找出<sum[i]时的最大值即可。
【AC CODE】125ms
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define rep(i,a,n) for(int i = a; i < n; i++)
#define repe(i,a,n) for(int i = a; i <= n; i++)
#define per(i,n,a) for(int i = n; i >= a; i--)
#define clc(a,b) memset(a,b,sizeof(a))
const int MAXN = 50000+10;
const LL INF = 0x3f3f3f3f3f3f3f3f;
int a[MAXN];
LL sum[MAXN];
LL mx[MAXN],cnt;
inline int lowbit(int x){return x&-x;}
void insert(int x, LL v)
{
while(x <= cnt)
{
mx[x] = max(mx[x],v);
x += lowbit(x);
}
}
LL query(int x)
{
LL ans = -4485090715960753727;
while(x > 0)
{
ans = max(ans,mx[x]);
x -= lowbit(x);
}
return ans;
}
LL sot[MAXN];
int main()
{
#ifdef SHY
freopen("d:\\1.txt", "r", stdin);
#endif
int n;
scanf("%d", &n);
clc(mx,-0x3f);
repe(i,1,n) scanf("%d", &a[i]);
repe(i,1,n) sum[i] = sum[i-1]+a[i],sot[i] = sum[i];
sort(sot,sot+n);
cnt = unique(sot,sot+n)-sot;
LL ans = INF;
//if(a[1] > 0) ans = a[1];
insert(lower_bound(sot,sot+cnt,0)-sot+1,0);
repe(i,1,n)
{
int x = lower_bound(sot,sot+cnt,sum[i])-sot+1;
ans = min(ans,sum[i]-query(x-1));
insert(x,sum[i]);
}
printf("%lld\n", ans);
return 0;
}