#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<queue>
using namespace std;
typedef vector<int> VI;
typedef long long LL;
#define FOR(x, b, e) for(int x=b; x<=(e); ++x)
#define FORD(x, b, e) for(int x=b; x>=(e); --x)
#define REP(x, n) for(int x=0; x<(n); ++x)
#define VAR(v, n) __typeof(n) v = (n)
#define ALL(c) (c).begin(), (c).end()
#define SIZE(x) ((int)(x).size())
#define FOREACH(i, c) for(VAR(i, (c).begin()); i != (c).end(); ++i)
#define PB push_back
#define ST first
#define ND second
struct Vert {
Vert *prev, *next;
int val, dist, distsum = 0;
LL sum;
Vert(int v, int d): val(v), dist(d), sum(v) {
prev = next = 0;
}
};
struct List {
Vert *begin, *end;
void add(int v, int d) {
Vert *tmp = new Vert(v, d);
if(begin == 0) begin = end = tmp;
else {
tmp->sum += end->sum;
end->next = tmp;
tmp->prev = end;
end = tmp;
}
}
};
void printList(List *l) {
Vert *b = l->begin;
while(b != 0) {
printf("(%d, %d) -> ", b->val, b->dist);
b = b->next;
}
printf("\n");
}
int main() {
ios_base::sync_with_stdio(0);
int n;
cin >> n;
List *list = new List;
LL sum = 0;
int prev = 0;
REP(i, n) {
int a;
cin >> a;
if(a == 0) continue;
sum += a;
list->add(a, i - prev);
prev = i;
}
if(sum < 0) {
cout << "-1\n";
} else {
int res = 0;
Vert *b = list->begin;
while(true) {
//printList(list);
Vert *f = b;
while(f != 0 && f->val >= 0) {
if(f->next != 0) f->next->distsum = f->next->dist + f->distsum;
f = f->next;
}
if(f == 0) {
cout << res << '\n';
return 0;
}
while(b->prev != 0 && f->sum - b->sum + b->val < 0) b = b->prev;
Vert *e = f;
while((e->sum - b->sum + b->val) < 0) {
if(e->next != 0) e->next->distsum = e->next->dist + e->distsum;
e = e->next;
}
while((e->sum - b->sum) >= 0 && b != f && b->next != e) {
if(b->next != 0) b->next->distsum = b->next->dist + b->distsum;
b = b->next;
}
Vert *tb = b->next;
Vert *te = e;
while(tb != f->next) {
while(te != 0 && te->sum - tb->sum + tb->val < 0 && te->distsum - tb->distsum <= e->distsum - b->distsum) {
if(te->next != 0) te->next->distsum = te->next->dist + te->distsum;
te = te->next;
}
while(te != 0 && (te->sum - tb->sum) >= 0 && tb != f) tb = tb->next;
if(te != 0 && te->distsum - tb->distsum <= e->distsum - b->distsum) {
b = tb;
e = te;
}
tb = tb->next;
}
res += e->distsum - b->distsum;
b->val += e->sum - b->sum;
b->next = e->next;
b->sum = e->sum;
if(b->next != 0) b->next->prev = b;
}
}
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 | #include<cstdio> #include<iostream> #include<algorithm> #include<string> #include<vector> #include<queue> using namespace std; typedef vector<int> VI; typedef long long LL; #define FOR(x, b, e) for(int x=b; x<=(e); ++x) #define FORD(x, b, e) for(int x=b; x>=(e); --x) #define REP(x, n) for(int x=0; x<(n); ++x) #define VAR(v, n) __typeof(n) v = (n) #define ALL(c) (c).begin(), (c).end() #define SIZE(x) ((int)(x).size()) #define FOREACH(i, c) for(VAR(i, (c).begin()); i != (c).end(); ++i) #define PB push_back #define ST first #define ND second struct Vert { Vert *prev, *next; int val, dist, distsum = 0; LL sum; Vert(int v, int d): val(v), dist(d), sum(v) { prev = next = 0; } }; struct List { Vert *begin, *end; void add(int v, int d) { Vert *tmp = new Vert(v, d); if(begin == 0) begin = end = tmp; else { tmp->sum += end->sum; end->next = tmp; tmp->prev = end; end = tmp; } } }; void printList(List *l) { Vert *b = l->begin; while(b != 0) { printf("(%d, %d) -> ", b->val, b->dist); b = b->next; } printf("\n"); } int main() { ios_base::sync_with_stdio(0); int n; cin >> n; List *list = new List; LL sum = 0; int prev = 0; REP(i, n) { int a; cin >> a; if(a == 0) continue; sum += a; list->add(a, i - prev); prev = i; } if(sum < 0) { cout << "-1\n"; } else { int res = 0; Vert *b = list->begin; while(true) { //printList(list); Vert *f = b; while(f != 0 && f->val >= 0) { if(f->next != 0) f->next->distsum = f->next->dist + f->distsum; f = f->next; } if(f == 0) { cout << res << '\n'; return 0; } while(b->prev != 0 && f->sum - b->sum + b->val < 0) b = b->prev; Vert *e = f; while((e->sum - b->sum + b->val) < 0) { if(e->next != 0) e->next->distsum = e->next->dist + e->distsum; e = e->next; } while((e->sum - b->sum) >= 0 && b != f && b->next != e) { if(b->next != 0) b->next->distsum = b->next->dist + b->distsum; b = b->next; } Vert *tb = b->next; Vert *te = e; while(tb != f->next) { while(te != 0 && te->sum - tb->sum + tb->val < 0 && te->distsum - tb->distsum <= e->distsum - b->distsum) { if(te->next != 0) te->next->distsum = te->next->dist + te->distsum; te = te->next; } while(te != 0 && (te->sum - tb->sum) >= 0 && tb != f) tb = tb->next; if(te != 0 && te->distsum - tb->distsum <= e->distsum - b->distsum) { b = tb; e = te; } tb = tb->next; } res += e->distsum - b->distsum; b->val += e->sum - b->sum; b->next = e->next; b->sum = e->sum; if(b->next != 0) b->next->prev = b; } } return 0; } |
English