#include<bits/stdc++.h> using namespace std; int n; int energy[500000+69]; long long pref[500000+69]; int after[500000+69]; int tree[(2<<20)+69]; int arr[500000+69]; int mapa[500000+69]; bool cmp(int a,int b){ return (pref[n]-pref[after[a+1]-1]>pref[n]-pref[after[b+1]-1]); } int mnp(int v,int mp,int mk,int p,int k){ if(p<=mp && mk<=k) return tree[v]; if(mk<p || k<mp) return 1000000000+69; return min(mnp(v*2,mp,(mp+mk)/2,p,k),mnp(v*2+1,(mp+mk+1)/2,mk,p,k)); } int main(){ int m,i,r,v,pom,p,k,s,ost,pie; scanf("%d",&n); for(i=1;i<=n;i++) scanf("%d",&energy[i]); i=n; while(energy[i]==0 && i>0) i--; if(i==0){ printf("0\n"); return 0; } after[i]=i; ost=i; pie=i; i--; while(i>=0){ after[i]=after[i+1]; if(energy[i]!=0){ after[i]=i; pie=i; } i--; } for(i=1;i<=n;i++) pref[i]=pref[i-1]+energy[i]; m=1; arr[0]=0; for(i=1;i<=n;i++) if(energy[i]!=0 && pref[i]>=0 && pref[n]-pref[after[i+1]-1]>=0) arr[m++]=i; if(pref[n]<0){ printf("-1\n"); return 0; } m--; sort(arr,arr+m,cmp); for(i=0;i<m;i++) mapa[arr[i]]=i; r=1; while(r<m) r*=2; for(i=0;i<r;i++) tree[r+i]=1000000000+69; for(i=r-1;i>=1;i--) tree[i]=1000000000+69; tree[r+mapa[0]]=n-1; v=(r+mapa[0])/2; while(v>0){ tree[v]=min(tree[2*v],tree[2*v+1]); v/=2; } //printf("ost: %d\n",ost); for(i=1;i<ost;i++) if(energy[i]!=0 && pref[i]>=0 && pref[n]-pref[after[i+1]-1]>=0){ p=0; k=m-1; while(p<k){ s=(p+k+1)/2; //printf("i: %d p: %d k: %d s: %d\n",i,p,k,s); if(pref[i]-pref[after[arr[s]+1]-1]>=0) p=s; else k=s-1; } //printf("binsearch: %d arr: %d\n",p,arr[p]); s=p; if(pref[i]-pref[after[arr[s]+1]-1]>=0){ //printf("ok\n"); pom=mnp(1,0,r-1,0,s); //printf("pom: %d tree: %d %d %d %d %d %d %d %d\n",pom,tree[r],tree[r+1],tree[r+2],tree[r+3],tree[r+4],tree[r+5],tree[r+6],tree[r+7]); tree[r+mapa[i]]=pom-(after[i+1]-i); //printf("tree[%d]:=%d\n",mapa[i],pom-(after[i+1]-i)); v=(r+mapa[i])/2; while(v>0){ tree[v]=min(tree[2*v],tree[2*v+1]); v/=2; } } } //for(i=0;i<m;i++) //printf("i: %d pos: %d cost: %d\n",i,arr[i].pos,arr[i].cost); printf("%d\n",tree[1]-(n-ost)-(pie-1)); return 0; }
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 92 93 94 95 96 97 98 99 100 101 102 103 104 | #include<bits/stdc++.h> using namespace std; int n; int energy[500000+69]; long long pref[500000+69]; int after[500000+69]; int tree[(2<<20)+69]; int arr[500000+69]; int mapa[500000+69]; bool cmp(int a,int b){ return (pref[n]-pref[after[a+1]-1]>pref[n]-pref[after[b+1]-1]); } int mnp(int v,int mp,int mk,int p,int k){ if(p<=mp && mk<=k) return tree[v]; if(mk<p || k<mp) return 1000000000+69; return min(mnp(v*2,mp,(mp+mk)/2,p,k),mnp(v*2+1,(mp+mk+1)/2,mk,p,k)); } int main(){ int m,i,r,v,pom,p,k,s,ost,pie; scanf("%d",&n); for(i=1;i<=n;i++) scanf("%d",&energy[i]); i=n; while(energy[i]==0 && i>0) i--; if(i==0){ printf("0\n"); return 0; } after[i]=i; ost=i; pie=i; i--; while(i>=0){ after[i]=after[i+1]; if(energy[i]!=0){ after[i]=i; pie=i; } i--; } for(i=1;i<=n;i++) pref[i]=pref[i-1]+energy[i]; m=1; arr[0]=0; for(i=1;i<=n;i++) if(energy[i]!=0 && pref[i]>=0 && pref[n]-pref[after[i+1]-1]>=0) arr[m++]=i; if(pref[n]<0){ printf("-1\n"); return 0; } m--; sort(arr,arr+m,cmp); for(i=0;i<m;i++) mapa[arr[i]]=i; r=1; while(r<m) r*=2; for(i=0;i<r;i++) tree[r+i]=1000000000+69; for(i=r-1;i>=1;i--) tree[i]=1000000000+69; tree[r+mapa[0]]=n-1; v=(r+mapa[0])/2; while(v>0){ tree[v]=min(tree[2*v],tree[2*v+1]); v/=2; } //printf("ost: %d\n",ost); for(i=1;i<ost;i++) if(energy[i]!=0 && pref[i]>=0 && pref[n]-pref[after[i+1]-1]>=0){ p=0; k=m-1; while(p<k){ s=(p+k+1)/2; //printf("i: %d p: %d k: %d s: %d\n",i,p,k,s); if(pref[i]-pref[after[arr[s]+1]-1]>=0) p=s; else k=s-1; } //printf("binsearch: %d arr: %d\n",p,arr[p]); s=p; if(pref[i]-pref[after[arr[s]+1]-1]>=0){ //printf("ok\n"); pom=mnp(1,0,r-1,0,s); //printf("pom: %d tree: %d %d %d %d %d %d %d %d\n",pom,tree[r],tree[r+1],tree[r+2],tree[r+3],tree[r+4],tree[r+5],tree[r+6],tree[r+7]); tree[r+mapa[i]]=pom-(after[i+1]-i); //printf("tree[%d]:=%d\n",mapa[i],pom-(after[i+1]-i)); v=(r+mapa[i])/2; while(v>0){ tree[v]=min(tree[2*v],tree[2*v+1]); v/=2; } } } //for(i=0;i<m;i++) //printf("i: %d pos: %d cost: %d\n",i,arr[i].pos,arr[i].cost); printf("%d\n",tree[1]-(n-ost)-(pie-1)); return 0; } |