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
#include "bits/stdc++.h" // Tomasz Nowak
using namespace std;     // XIII LO Szczecin
using LL = long long;    // Poland
#define FOR(i, l, r) for(int i = (l); i <= (r); ++i)
#define REP(i, n) FOR(i, 0, (n) - 1)
template<class T> int size(T &&x) {
	return int(x.size());
}
template<class A, class B> ostream& operator<<(ostream &out, const pair<A, B> &p) {
	return out << '(' << p.first << ", " << p.second << ')';
}
template<class T> auto operator<<(ostream &out, T &&x) -> decltype(x.begin(), out) {
	out << '{';
	for(auto it = x.begin(); it != x.end(); ++it)
		out << *it << (it == prev(x.end()) ? "" : ", ");
	return out << '}';
}
void dump() {}
template<class T, class... Args> void dump(T &&x, Args... args) {
	cerr << x << ";  ";
	dump(args...);
}
#ifdef DEBUG
  struct Nl{~Nl(){cerr << '\n';}};
# define debug(x...) cerr << (strcmp(#x, "") ? #x ":  " : ""), dump(x), Nl(), cerr << ""
#else
# define debug(...) 0 && cerr
#endif
mt19937_64 rng(0);
int rd(int l, int r) {
	return uniform_int_distribution<int>(l, r)(rng);
}
// end of templates

void scale(vector<LL> &v) {
	int n = size(v);
	vector<pair<LL, int>> sorted(n);
	REP(i, n)
		sorted[i] = {v[i], i};
	sort(sorted.begin(), sorted.end());

	v[sorted[0].second] = 0;
	for(int i = 1; i < n; ++i)
		v[sorted[i].second] = v[sorted[i - 1].second]
			+ bool(sorted[i].first != sorted[i - 1].first);
}

struct PrefixMin {
	int n;
	vector<int> t;
	PrefixMin(int _n) : n(_n), t(n + 1, n) {}

	void set(int i, int val) {
		for(++i; i > 0; i -= i & (-i))
			t[i] = min(t[i], val);
	}

	int get(int i) {
		int ret = n;
		for(++i; i <= n; i += i & (-i))
			ret = min(ret, t[i]);
		return ret;
	}
};

struct SuffixMin {
	int n;
	PrefixMin p;
	SuffixMin(int _n) : n(_n), p(_n) {}

	void set(int i, int val) {
		p.set(n - 1 - i, val);
	}
	int get(int i) {
		int ret = p.get(n - 1 - i);
		return ret;
	}
};

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);

	int n;
	cin >> n;
	vector<int> a(n);
	for(int &ai : a)
		cin >> ai;

	vector<LL> pref_sum(n + 1);
	REP(i, n)
		pref_sum[i + 1] = a[i] + pref_sum[i];
	scale(pref_sum);

	vector dp(n, n);
	SuffixMin values(n + 1);
	for(int r = 0; r < n; ++r) {
		values.set(int(pref_sum[r]), (r == 0 ? 0 : dp[r - 1]) - r);
		int best_diff = values.get(int(pref_sum[r + 1]));
		debug(values.p.t);
		debug(r, pref_sum[r + 1], best_diff);
		dp[r] = best_diff + r;
	}

	int ans = dp.back();
	if(ans >= n)
		ans = -1;
	cout << ans << '\n';
}