#include<bits/stdc++.h> using namespace std; using LL = long long; using D = double; #define f1 first #define f2 second #define randint(a, b) uniform_int_distribution<int>{a, b}(gen) #ifdef LOC void OUT() {cout << '\n';} template<class H, class ... T> void OUT(H h, T ... t) { cout << h << ' '; OUT(t...); } #define P(...) cout << "[" << #__VA_ARGS__ << "] ", OUT(__VA_ARGS__) #else #define P(...) #define OUT(...) #endif //mt19937 gen; int n; LL val[500100]; struct TR { int id; LL val; bool operator<(const TR & a) const { return val < a.val; } }; TR tree[1<<20]; LL dp[500100]; int elToTree[500100]; vector<pair<int, int>> prefs; int depth = 4; void updateSingle(int i) { if(tree[2 * i] < tree[2 * i + 1]) tree[i] = tree[2 * i]; else tree[i] = tree[2 * i + 1]; } void update(int p) { while(p > 1) { p /= 2; updateSingle(p); } } void setTree(int p) { tree[elToTree[p] + depth].val = dp[p] - p; update(elToTree[p] + depth); } TR getMin(int st, int en, int a = 0, int b = depth - 1, int p = 1) { if(st <= a && b <= en) return tree[p]; if(b < st || en < a) return {-1, 999999999}; return min(getMin(st, en, a, (a+b) / 2, p * 2), getMin(st, en, (a+b) / 2 + 1, b, p * 2 + 1)); } void pr() { for(int i = 1; i < 2 * depth; ++i) { cout << tree[i].id << ' ' << tree[i].val << " | ";} cout << '\n'; } int main(int, char ** /*args*/) { ios_base::sync_with_stdio(0); cin.tie(0); //gen.seed(atoi(args[1])); cin >> n; ++n; LL prefsum = 0; val[0] = 0; prefs.push_back({0, 0}); for(int i = 1; i < n; ++i) { cin >> val[i]; prefsum += val[i]; prefs.push_back({prefsum, i}); } sort(prefs.begin(), prefs.end()); while(n + 3 >= depth) depth *= 2; for(int i = 0; i < (int) prefs.size(); ++i) { elToTree[prefs[i].f2] = i; } for(int i = 0; i < depth; ++i) tree[depth + i] = {i, 999999999}; for(int i = depth - 1; i >= 0; --i) updateSingle(i); dp[0] = 0; setTree(0); for(int i = 1; i < n; ++i) { auto t = getMin(0, elToTree[i] - 1); //pr(); //P(t.val, elToTree[i]); if(t.val > 10000000) dp[i] = 10000100 + i - 1; dp[i] = t.val + i - 1; if(val[i] >= 0) { dp[i] = min(dp[i], dp[i - 1]); } //P(dp[i]); setTree(i); } if(dp[n - 1] < 10000000) cout << dp[n - 1] << '\n'; else cout << -1 << '\n'; /*for(int i = 0; i < n; ++i) { cout << dp[i] << ' '; }*/ 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 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | #include<bits/stdc++.h> using namespace std; using LL = long long; using D = double; #define f1 first #define f2 second #define randint(a, b) uniform_int_distribution<int>{a, b}(gen) #ifdef LOC void OUT() {cout << '\n';} template<class H, class ... T> void OUT(H h, T ... t) { cout << h << ' '; OUT(t...); } #define P(...) cout << "[" << #__VA_ARGS__ << "] ", OUT(__VA_ARGS__) #else #define P(...) #define OUT(...) #endif //mt19937 gen; int n; LL val[500100]; struct TR { int id; LL val; bool operator<(const TR & a) const { return val < a.val; } }; TR tree[1<<20]; LL dp[500100]; int elToTree[500100]; vector<pair<int, int>> prefs; int depth = 4; void updateSingle(int i) { if(tree[2 * i] < tree[2 * i + 1]) tree[i] = tree[2 * i]; else tree[i] = tree[2 * i + 1]; } void update(int p) { while(p > 1) { p /= 2; updateSingle(p); } } void setTree(int p) { tree[elToTree[p] + depth].val = dp[p] - p; update(elToTree[p] + depth); } TR getMin(int st, int en, int a = 0, int b = depth - 1, int p = 1) { if(st <= a && b <= en) return tree[p]; if(b < st || en < a) return {-1, 999999999}; return min(getMin(st, en, a, (a+b) / 2, p * 2), getMin(st, en, (a+b) / 2 + 1, b, p * 2 + 1)); } void pr() { for(int i = 1; i < 2 * depth; ++i) { cout << tree[i].id << ' ' << tree[i].val << " | ";} cout << '\n'; } int main(int, char ** /*args*/) { ios_base::sync_with_stdio(0); cin.tie(0); //gen.seed(atoi(args[1])); cin >> n; ++n; LL prefsum = 0; val[0] = 0; prefs.push_back({0, 0}); for(int i = 1; i < n; ++i) { cin >> val[i]; prefsum += val[i]; prefs.push_back({prefsum, i}); } sort(prefs.begin(), prefs.end()); while(n + 3 >= depth) depth *= 2; for(int i = 0; i < (int) prefs.size(); ++i) { elToTree[prefs[i].f2] = i; } for(int i = 0; i < depth; ++i) tree[depth + i] = {i, 999999999}; for(int i = depth - 1; i >= 0; --i) updateSingle(i); dp[0] = 0; setTree(0); for(int i = 1; i < n; ++i) { auto t = getMin(0, elToTree[i] - 1); //pr(); //P(t.val, elToTree[i]); if(t.val > 10000000) dp[i] = 10000100 + i - 1; dp[i] = t.val + i - 1; if(val[i] >= 0) { dp[i] = min(dp[i], dp[i - 1]); } //P(dp[i]); setTree(i); } if(dp[n - 1] < 10000000) cout << dp[n - 1] << '\n'; else cout << -1 << '\n'; /*for(int i = 0; i < n; ++i) { cout << dp[i] << ' '; }*/ return 0; } |