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
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <set>
#include <map>
#include <array>
#include <random>
#include <cmath>
#include <list>
#include <ctime>
#include <sstream>
#include <queue>
#include <climits>
#include <stack>
#include <random>
#include <bitset>
#include <numeric>
#include <cassert>
using namespace std;
typedef vector<int> vi;
typedef pair<int,int> pii;
typedef long long ll;
#define rep(x, b, e) for(int x=(b); x<(e); ++x)
#define trav(a, x) for(auto& a : x)
#define ford(x, b, e) for(int x=((int)(b))-1; x>=(e); --x)
#define all(c) c.begin(),c.end()
#define sz(x) ((int)((x).size()))
#define pb push_back
#define st first
#define nd second
#define mp(x,y) make_pair(x,y)
typedef short int sint;

#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "

const int N = 1 << 20;
int P;
int t[N];

int getMin(int p, int q, int pocz = 1, int kon = P, int ind = 1) {
	if (p == pocz && q == kon) return t[ind];
	int sr = (pocz + kon) / 2;
	if (q <= sr) return getMin(p, q, pocz, sr, 2*ind);
	else if (p > sr) return getMin(p, q, sr + 1, kon, 2*ind + 1);
	return min(getMin(p, sr, pocz, sr, 2*ind), getMin(sr+1, q, sr+1, kon, 2*ind + 1));
}

void setuj(int pos, int val) {
	pos = pos + P - 1;
	t[pos] = val;
	while (pos/2) {
		pos /= 2;
		t[pos] = min(t[2*pos], t[2*pos + 1]);
	}
}

int main() {
	ios_base::sync_with_stdio(false); cin.tie(0);
	int n;
	scanf("%d", &n);
	ll s = 0;
	vector<pair<ll, int>> events;
	events.pb({s, 1});
	rep(i, 0, n) {
		int x;
		scanf("%d", &x);
		s += x;
		events.pb({s, i + 2});
	}
	++n;
	vi f(n + 1, INT_MAX);
	P = 1;
	while (P < n) P <<= 1;
	// printf("n: %d, P: %d\n", n, P);
	rep(i, 1, 2 * P) {
		t[i] = INT_MAX;
	}
	sort(all(events));
	trav(ev, events) {
		// rozwazam ev.nd
		int best;
		if (ev.nd  == 1)  {
			best = 0;
		} else {
			best = getMin(1, ev.nd);
		}
		if (best != INT_MAX) {
			best = best + ev.nd - 1;
		}
		f[ev.nd] = best;
		if (f[ev.nd] != INT_MAX) {
			setuj(ev.nd, f[ev.nd] - ev.nd);
		}
	}
	printf("%d\n", f[n] == INT_MAX ? -1 : f[n]);
}