#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]); } |