#include<bits/stdc++.h> using namespace std; const int max_cities = 5e5 + 9; int cities[max_cities]; long long pre_tree[4 * max_cities], suf_tree[4 * max_cities]; long long pre_sum[max_cities], suf_sum[max_cities]; //g++ -O3 -static 2B/2B2.cpp -std=c++11 -o 2B/2b2 vector<pair<int, pair<int, int> > > edges; void update(long long tree[], int ind){ ind /=2; while(ind > 0){ tree[ind] = max(tree[2 * ind], tree[2 * ind + 1]); ind /=2; } } long long query(long long tree[], int sq, int eq, int ind, int sc, int ec){ if(eq < sc || ec < sq){ return 0; } if(sq <= sc && ec <= eq){ return tree[ind]; } int mc = (sc + ec) / 2; return max(query(tree, sq, eq, 2 * ind, sc, mc), query(tree, sq, eq, 2 * ind + 1, mc + 1, ec)); } int main(){ ios_base::sync_with_stdio(0); cin.tie(0); int n; cin >> n; int base = 1; while(base < n){ base *= 2; } int zeros = 0; int pi = 0; for(int i = 0; i < n; i++){ cin >> cities[i]; if(i != 0){ pre_sum[i] = pre_sum[i-1] + cities[i]; if(cities[i] == 0){ zeros ++; }else{ edges.push_back({zeros + 1, {pi, i}}); zeros = 0; pi = i; } }else{ pre_sum[0] = cities[0]; } } suf_sum[n-1] = cities[n-1]; for(int i = n-2; i >= 0; i--){ suf_sum[i] = cities[i] + suf_sum[i+1]; } sort(edges.begin(), edges.end(), greater <pair<int, pair<int, int> > >()); int result = 0; for(auto edge : edges){ int v1 = edge.second.first; int v2 = edge.second.second; long long pre = pre_sum[v1] - query(pre_tree, 0, v1, 1, 0, base - 1); long long suf = suf_sum[v2] - query(suf_tree, v2, base - 1, 1, 0, base - 1); if(pre + suf < 0){ cout << "-1"; return 0; } if(pre >= 0 && suf >= 0){ pre_tree[base + v1] = pre_sum[v1]; suf_tree[base + v2] = suf_sum[v2]; update(pre_tree, base + v1); update(suf_tree, base + v2); }else{ result += edge.first; } } cout << result; 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 | #include<bits/stdc++.h> using namespace std; const int max_cities = 5e5 + 9; int cities[max_cities]; long long pre_tree[4 * max_cities], suf_tree[4 * max_cities]; long long pre_sum[max_cities], suf_sum[max_cities]; //g++ -O3 -static 2B/2B2.cpp -std=c++11 -o 2B/2b2 vector<pair<int, pair<int, int> > > edges; void update(long long tree[], int ind){ ind /=2; while(ind > 0){ tree[ind] = max(tree[2 * ind], tree[2 * ind + 1]); ind /=2; } } long long query(long long tree[], int sq, int eq, int ind, int sc, int ec){ if(eq < sc || ec < sq){ return 0; } if(sq <= sc && ec <= eq){ return tree[ind]; } int mc = (sc + ec) / 2; return max(query(tree, sq, eq, 2 * ind, sc, mc), query(tree, sq, eq, 2 * ind + 1, mc + 1, ec)); } int main(){ ios_base::sync_with_stdio(0); cin.tie(0); int n; cin >> n; int base = 1; while(base < n){ base *= 2; } int zeros = 0; int pi = 0; for(int i = 0; i < n; i++){ cin >> cities[i]; if(i != 0){ pre_sum[i] = pre_sum[i-1] + cities[i]; if(cities[i] == 0){ zeros ++; }else{ edges.push_back({zeros + 1, {pi, i}}); zeros = 0; pi = i; } }else{ pre_sum[0] = cities[0]; } } suf_sum[n-1] = cities[n-1]; for(int i = n-2; i >= 0; i--){ suf_sum[i] = cities[i] + suf_sum[i+1]; } sort(edges.begin(), edges.end(), greater <pair<int, pair<int, int> > >()); int result = 0; for(auto edge : edges){ int v1 = edge.second.first; int v2 = edge.second.second; long long pre = pre_sum[v1] - query(pre_tree, 0, v1, 1, 0, base - 1); long long suf = suf_sum[v2] - query(suf_tree, v2, base - 1, 1, 0, base - 1); if(pre + suf < 0){ cout << "-1"; return 0; } if(pre >= 0 && suf >= 0){ pre_tree[base + v1] = pre_sum[v1]; suf_tree[base + v2] = suf_sum[v2]; update(pre_tree, base + v1); update(suf_tree, base + v2); }else{ result += edge.first; } } cout << result; return 0; } |