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