#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; } |
English