#include <bits/stdc++.h> using namespace std; using ll = long long; const int INF = 1e9; struct MinTree { int S; vector<int> nodes; MinTree(int n) { S = 1; while (S < n) { S *= 2; } nodes.resize(2 * S, INF); } void update(int p, int x) { p += S; while (p) { nodes[p] = min(nodes[p], x); p /= 2; } } int query(int l, int r) { l += S; r += S; int res = min(nodes[l], nodes[r]); while (l / 2 != r / 2) { if (l % 2 == 0) { res = min(res, nodes[l + 1]); } if (r % 2 == 1) { res = min(res, nodes[r - 1]); } l /= 2; r /= 2; } return res; } }; map<ll, int> scale(vector<ll> seq) { map<ll, int> res; sort(seq.begin(), seq.end()); int stat = 0; for (ll x : seq) { res[x] = stat; stat++; } return res; } void solve(int n, const vector<int> &a) { vector<ll> lsum(n + 1); for (int i = 1; i <= n; i++) { lsum[i] = lsum[i - 1] + a[i]; } auto lsumScale = scale(lsum); vector<int> dp(n + 1); MinTree tree(n + 1); tree.update(lsumScale[0], 0); for (int i = 1; i <= n; i++) { dp[i] = (i - 1) + tree.query(0, lsumScale[lsum[i]]); if (dp[i] < INF) { tree.update(lsumScale[lsum[i]], dp[i] - i); } } int res = dp[n]; if (res >= INF) { cout << "-1\n"; } else { cout << res << "\n"; } } int main() { ios_base::sync_with_stdio(false); int n; cin >> n; vector<int> a(n + 1); for (int i = 1; i <= n; i++) { cin >> a[i]; } solve(n, a); }
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; using ll = long long; const int INF = 1e9; struct MinTree { int S; vector<int> nodes; MinTree(int n) { S = 1; while (S < n) { S *= 2; } nodes.resize(2 * S, INF); } void update(int p, int x) { p += S; while (p) { nodes[p] = min(nodes[p], x); p /= 2; } } int query(int l, int r) { l += S; r += S; int res = min(nodes[l], nodes[r]); while (l / 2 != r / 2) { if (l % 2 == 0) { res = min(res, nodes[l + 1]); } if (r % 2 == 1) { res = min(res, nodes[r - 1]); } l /= 2; r /= 2; } return res; } }; map<ll, int> scale(vector<ll> seq) { map<ll, int> res; sort(seq.begin(), seq.end()); int stat = 0; for (ll x : seq) { res[x] = stat; stat++; } return res; } void solve(int n, const vector<int> &a) { vector<ll> lsum(n + 1); for (int i = 1; i <= n; i++) { lsum[i] = lsum[i - 1] + a[i]; } auto lsumScale = scale(lsum); vector<int> dp(n + 1); MinTree tree(n + 1); tree.update(lsumScale[0], 0); for (int i = 1; i <= n; i++) { dp[i] = (i - 1) + tree.query(0, lsumScale[lsum[i]]); if (dp[i] < INF) { tree.update(lsumScale[lsum[i]], dp[i] - i); } } int res = dp[n]; if (res >= INF) { cout << "-1\n"; } else { cout << res << "\n"; } } int main() { ios_base::sync_with_stdio(false); int n; cin >> n; vector<int> a(n + 1); for (int i = 1; i <= n; i++) { cin >> a[i]; } solve(n, a); } |