#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
typedef double db;
//mt19937 mrand(random_device{}());
const ll mod=1000000007;
//int rnd(int x) { return mrand() % x;}
ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
int gcd(int a,int b) { return b?gcd(b,a%b):a;}
// head
const int N=7e5+5;
#define INF 0x3f3f3f3f
template<class T> inline void read(T &x) {
x=0; int c=getchar(),f=1;
for (;!isdigit(c);c=getchar()) if (c==45) f=-1;
for (;isdigit(c);c=getchar()) (x*=10)+=f*(c-'0');
}
int n,a[N],id[N],dp[N],nd[2*N];
pair<ll,int> pref[N];
void push(int p) {
nd[p+p]=min(nd[p+p],nd[p]);
nd[p+p+1]=min(nd[p+p+1],nd[p]);
nd[p]=INF;
}
void build(int p,int l,int r) {
if (l==r) {
nd[p]=INF;
if (pref[l].fi>=0) nd[p]=0;
return;
}
int md=(l+r)>>1;
build(p+p,l,md);
build(p+p+1,md+1,r);
nd[p]=INF;
}
void modify(int p,int l,int r,int tl,int tr,int val) {
if (l==tl&&tr==r) {
nd[p]=min(nd[p],val);
return;
}
if (nd[p]!=INF) push(p);
int md=(l+r)>>1;
if (tr<=md) modify(p+p,l,md,tl,tr,val);
else if (tl>md) modify(p+p+1,md+1,r,tl,tr,val);
else modify(p+p,l,md,tl,md,val),modify(p+p+1,md+1,r,md+1,tr,val);
}
int query(int p,int l,int r,int x) {
if (l==r) return nd[p];
if (nd[p]!=INF) push(p);
int md=(l+r)>>1;
if (x<=md) return query(p+p,l,md,x);
return query(p+p+1,md+1,r,x);
}
int main() {
read(n);
rep(i,0,n) read(a[i]);
pref[0]=mp(a[0],0);
rep(i,1,n) pref[i]=mp(pref[i-1].fi+a[i],i);
sort(pref,pref+n);
build(1,0,n-1);
rep(i,0,n) id[pref[i].se]=i;
int curMin=INF;
rep(i,0,n-1) {
dp[i]=query(1,0,n-1,id[i]);
if (dp[i]!=INF) dp[i]+=i;
if (a[i]<0) curMin=INF;
curMin=min(curMin,dp[i]);
if (id[i]+1<n&&curMin!=INF) modify(1,0,n-1,id[i]+1,n-1,curMin-i-1);
}
dp[n-1]=query(1,0,n-1,id[n-1]);
if (dp[n-1]==INF) puts("-1");
else printf("%d\n",n-1+dp[n-1]);
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | #include <bits/stdc++.h> using namespace std; #define rep(i,a,n) for (int i=a;i<n;i++) #define per(i,a,n) for (int i=n-1;i>=a;i--) #define pb push_back #define mp make_pair #define all(x) (x).begin(),(x).end() #define fi first #define se second #define SZ(x) ((int)(x).size()) typedef vector<int> VI; typedef long long ll; typedef pair<int,int> PII; typedef double db; //mt19937 mrand(random_device{}()); const ll mod=1000000007; //int rnd(int x) { return mrand() % x;} ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;} int gcd(int a,int b) { return b?gcd(b,a%b):a;} // head const int N=7e5+5; #define INF 0x3f3f3f3f template<class T> inline void read(T &x) { x=0; int c=getchar(),f=1; for (;!isdigit(c);c=getchar()) if (c==45) f=-1; for (;isdigit(c);c=getchar()) (x*=10)+=f*(c-'0'); } int n,a[N],id[N],dp[N],nd[2*N]; pair<ll,int> pref[N]; void push(int p) { nd[p+p]=min(nd[p+p],nd[p]); nd[p+p+1]=min(nd[p+p+1],nd[p]); nd[p]=INF; } void build(int p,int l,int r) { if (l==r) { nd[p]=INF; if (pref[l].fi>=0) nd[p]=0; return; } int md=(l+r)>>1; build(p+p,l,md); build(p+p+1,md+1,r); nd[p]=INF; } void modify(int p,int l,int r,int tl,int tr,int val) { if (l==tl&&tr==r) { nd[p]=min(nd[p],val); return; } if (nd[p]!=INF) push(p); int md=(l+r)>>1; if (tr<=md) modify(p+p,l,md,tl,tr,val); else if (tl>md) modify(p+p+1,md+1,r,tl,tr,val); else modify(p+p,l,md,tl,md,val),modify(p+p+1,md+1,r,md+1,tr,val); } int query(int p,int l,int r,int x) { if (l==r) return nd[p]; if (nd[p]!=INF) push(p); int md=(l+r)>>1; if (x<=md) return query(p+p,l,md,x); return query(p+p+1,md+1,r,x); } int main() { read(n); rep(i,0,n) read(a[i]); pref[0]=mp(a[0],0); rep(i,1,n) pref[i]=mp(pref[i-1].fi+a[i],i); sort(pref,pref+n); build(1,0,n-1); rep(i,0,n) id[pref[i].se]=i; int curMin=INF; rep(i,0,n-1) { dp[i]=query(1,0,n-1,id[i]); if (dp[i]!=INF) dp[i]+=i; if (a[i]<0) curMin=INF; curMin=min(curMin,dp[i]); if (id[i]+1<n&&curMin!=INF) modify(1,0,n-1,id[i]+1,n-1,curMin-i-1); } dp[n-1]=query(1,0,n-1,id[n-1]); if (dp[n-1]==INF) puts("-1"); else printf("%d\n",n-1+dp[n-1]); } |
English