#include<iostream>
#include<vector>
#include<algorithm>
#include<climits>
using namespace std;
#define PII pair< int, int >
#define PLI pair< long long, int >
#define VPII vector< PII >
#define VPLI vector< PLI >
#define MP make_pair
#define REP(i,n) for(int i=0;i<(n);++i)
#define FOR(i,a,b) for (int i=(a); i<(b); ++i)
#define FORD(i,a,b) for (int i=(a)-1; i>=(b); --i)
#define EACH(a, x) for (auto& a : (x))
#define ALL(x) (x).begin(), (x).end()
#define INF INT_MAX
int n;
vector<int> dp;
VPLI prefsums;
vector<long long> ps;
// https://codeforces.com/blog/entry/18051
void modify_dp(int p, int value) {
for (dp[p += n + 1] = value; p > 1; p >>= 1) {
dp[p >> 1] = min(dp[p], dp[p ^ 1]);
}
}
int query_dp(int l, int r) {
int res = INF;
for (l += n + 1, r += n + 1; l < r; l >>= 1, r >>= 1) {
if (l & 1) {
int v = dp[l++];
if (v < res) {
res = v;
}
}
if (r & 1) {
int v = dp[--r];
if (v < res) {
res = v;
}
}
}
return res;
}
int ub(long long v) {
int begin = 0;
int end = n + 1;
while (end > begin) {
int mid = (begin + end) / 2;
long long vv = prefsums[mid].first;
if (vv <= v) {
begin = mid + 1;
} else {
end = mid;
}
}
return begin;
// REP(i, n + 1) {
// if (prefsums[i].first > v) {
// return i;
// }
// }
// return n;
}
int minv(int ptl) {
return query_dp(0, ptl);
// int m = INF;
// REP(i, ptl) {
// if (dp[i] < m) {
// m = dp[i];
// }
// }
// return m;
}
int main() {
ios_base::sync_with_stdio(0);
cin >> n;
prefsums.reserve(n + 2);
ps.reserve(n + 2);
dp.reserve(2 * n + 4);
prefsums.push_back(MP(0, 0));
ps.push_back(0);
long long x;
REP(i, n) {
cin >> x;
prefsums.push_back(MP(prefsums.back().first + x, i + 1));
ps.push_back(ps.back() + x);
}
for (int i = 0; i < 2 * n + 2; i++) {
dp.push_back(INF);
}
sort(prefsums.begin(), prefsums.end());
vector<int> mapping(n + 2, 0);
int i = 0;
EACH(elem, prefsums) {
mapping[elem.second] = i;
i++;
}
modify_dp(mapping[0], n);
REP(i, n) {
int first_bad = ub(ps[i + 1]);
int res = minv(first_bad);
modify_dp(mapping[i + 1], res - 1);
}
int ans = dp[mapping[n] + n + 1];
if(ans > n - 1) {
ans = -1;
}
cout << ans << endl;
}
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 | #include<iostream> #include<vector> #include<algorithm> #include<climits> using namespace std; #define PII pair< int, int > #define PLI pair< long long, int > #define VPII vector< PII > #define VPLI vector< PLI > #define MP make_pair #define REP(i,n) for(int i=0;i<(n);++i) #define FOR(i,a,b) for (int i=(a); i<(b); ++i) #define FORD(i,a,b) for (int i=(a)-1; i>=(b); --i) #define EACH(a, x) for (auto& a : (x)) #define ALL(x) (x).begin(), (x).end() #define INF INT_MAX int n; vector<int> dp; VPLI prefsums; vector<long long> ps; // https://codeforces.com/blog/entry/18051 void modify_dp(int p, int value) { for (dp[p += n + 1] = value; p > 1; p >>= 1) { dp[p >> 1] = min(dp[p], dp[p ^ 1]); } } int query_dp(int l, int r) { int res = INF; for (l += n + 1, r += n + 1; l < r; l >>= 1, r >>= 1) { if (l & 1) { int v = dp[l++]; if (v < res) { res = v; } } if (r & 1) { int v = dp[--r]; if (v < res) { res = v; } } } return res; } int ub(long long v) { int begin = 0; int end = n + 1; while (end > begin) { int mid = (begin + end) / 2; long long vv = prefsums[mid].first; if (vv <= v) { begin = mid + 1; } else { end = mid; } } return begin; // REP(i, n + 1) { // if (prefsums[i].first > v) { // return i; // } // } // return n; } int minv(int ptl) { return query_dp(0, ptl); // int m = INF; // REP(i, ptl) { // if (dp[i] < m) { // m = dp[i]; // } // } // return m; } int main() { ios_base::sync_with_stdio(0); cin >> n; prefsums.reserve(n + 2); ps.reserve(n + 2); dp.reserve(2 * n + 4); prefsums.push_back(MP(0, 0)); ps.push_back(0); long long x; REP(i, n) { cin >> x; prefsums.push_back(MP(prefsums.back().first + x, i + 1)); ps.push_back(ps.back() + x); } for (int i = 0; i < 2 * n + 2; i++) { dp.push_back(INF); } sort(prefsums.begin(), prefsums.end()); vector<int> mapping(n + 2, 0); int i = 0; EACH(elem, prefsums) { mapping[elem.second] = i; i++; } modify_dp(mapping[0], n); REP(i, n) { int first_bad = ub(ps[i + 1]); int res = minv(first_bad); modify_dp(mapping[i + 1], res - 1); } int ans = dp[mapping[n] + n + 1]; if(ans > n - 1) { ans = -1; } cout << ans << endl; } |
English