// Jakub Rozek // Elektrownie i fabryki [B] // potyczki 2020 // O( n*log(n) ) #include <bits/stdc++.h> using namespace std; const int N=500005; const int R=524288; struct struc{ long long w,sp; int p; }; int n,q,qq,odp,r; long long x; vector <struc> v; vector <long long> sp; map <long long , int> m; int dp[N]; int tree[R*2+2]; void insert(int a, int b) { a+=r; while(a) { tree[a]=min(tree[a],b); a/=2; } } int query(int w, int a, int b, int c, int d) { if(b<c || a>d) return 1000000009; if(c<=a && b<=d) return tree[w]; else return min(query(w*2, a, (a+b)/2 ,c,d), query(w*2+1, (a+b)/2+1, b ,c,d)); } int main() { ios_base::sync_with_stdio(0); cin.tie(0); v.push_back({0,0}); sp.push_back(0); cin>>n; for(int i=1; i<=n; ++i) { cin>>x; if(x==0) continue; if(v[q].sp<0) { sp.pop_back(); odp+=i-qq; v[q].w+=x; v[q].sp+=x; } else { v.push_back({x, v[q].sp+x, i-odp}); ++q; } sp.push_back(v[q].sp); qq=i; } if(v[q].sp<0) { cout<<"-1"; return 0; } sort(sp.begin(), sp.end()); qq=0; x=-1000000009; for(int i=0; i<(int)sp.size(); ++i) { if(sp[i]==x) continue; x=sp[i]; m[x]=qq; ++qq; } r=1; while(r<=qq) r*=2; for(int i=1; i<2*r; ++i) tree[i]=1000000009; for(int i=1; i<=q; ++i) { insert(m[v[i-1].sp], dp[i-1]-v[i].p); dp[i]=v[i].p+query(1,0,r-1,0,m[v[i].sp]); } cout<<odp+dp[q]; 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 | // Jakub Rozek // Elektrownie i fabryki [B] // potyczki 2020 // O( n*log(n) ) #include <bits/stdc++.h> using namespace std; const int N=500005; const int R=524288; struct struc{ long long w,sp; int p; }; int n,q,qq,odp,r; long long x; vector <struc> v; vector <long long> sp; map <long long , int> m; int dp[N]; int tree[R*2+2]; void insert(int a, int b) { a+=r; while(a) { tree[a]=min(tree[a],b); a/=2; } } int query(int w, int a, int b, int c, int d) { if(b<c || a>d) return 1000000009; if(c<=a && b<=d) return tree[w]; else return min(query(w*2, a, (a+b)/2 ,c,d), query(w*2+1, (a+b)/2+1, b ,c,d)); } int main() { ios_base::sync_with_stdio(0); cin.tie(0); v.push_back({0,0}); sp.push_back(0); cin>>n; for(int i=1; i<=n; ++i) { cin>>x; if(x==0) continue; if(v[q].sp<0) { sp.pop_back(); odp+=i-qq; v[q].w+=x; v[q].sp+=x; } else { v.push_back({x, v[q].sp+x, i-odp}); ++q; } sp.push_back(v[q].sp); qq=i; } if(v[q].sp<0) { cout<<"-1"; return 0; } sort(sp.begin(), sp.end()); qq=0; x=-1000000009; for(int i=0; i<(int)sp.size(); ++i) { if(sp[i]==x) continue; x=sp[i]; m[x]=qq; ++qq; } r=1; while(r<=qq) r*=2; for(int i=1; i<2*r; ++i) tree[i]=1000000009; for(int i=1; i<=q; ++i) { insert(m[v[i-1].sp], dp[i-1]-v[i].p); dp[i]=v[i].p+query(1,0,r-1,0,m[v[i].sp]); } cout<<odp+dp[q]; return(0); } |