#include <cstdio> #include <algorithm> using namespace std; #define LL long long #define MAXI 1000000000000000LL struct node { node *left, *right; int result; node(){ left = nullptr; right = nullptr; result = 1000000; } }; node* root = new node(); void add_tree(node* pos, LL s, LL cs, LL ce, int val){ if ((s == cs) && (s == ce)){ pos->result = min(pos->result, val); return; } else if (s <= (cs + ce)/2){ if (pos->left == nullptr){ pos->left = new node(); } add_tree(pos->left, s, cs, (cs + ce)/2, val); } else if (s > (cs + ce)/2){ if (pos->right == nullptr){ pos->right = new node(); } add_tree(pos->right, s, (cs + ce)/2 + 1, ce, val); } if ((pos->left != nullptr) && (pos->right != nullptr)){ pos->result = min(pos->left->result, pos->right->result); } else if (pos->left != nullptr){ pos->result = pos->left->result; } else { pos->result = pos->right->result; } } int get_tree(node* pos, LL s, LL e, LL cs, LL ce){ int def = 1000000; if ((s == cs) && (e == ce)){ if (pos == nullptr){ return def; } else { return pos->result; } } else if ((s <= (cs + ce)/2) && (e <= (cs + ce)/2)){ if (pos->left != nullptr){ return get_tree(pos->left, s, e, cs, (cs + ce)/2); } else { return def; } } else if ((s > (cs + ce)/2) && (e > (cs + ce)/2)){ if (pos->right != nullptr){ return get_tree(pos->right, s, e, (cs + ce)/2 + 1, ce); } else { return def; } } else { int r = def; if (pos->left != nullptr){ r = min(r, get_tree(pos->left, s, (cs + ce)/2, cs, (cs + ce)/2)); } if (pos->right != nullptr){ r = min(r, get_tree(pos->right, (cs + ce)/2 + 1, e, (cs + ce)/2+1, ce)); } return r; } } int t[500005], n; int main(){ scanf("%d", &n); LL tmp = 0; for (int i = 1; i <= n; i++){ scanf("%d", &t[i]); tmp += t[i]; } if (tmp < 0){ printf("-1\n"); return 0; } add_tree(root, 0, 0, MAXI, 0); int lr = 0; LL s = 0; for (int i = 1; i <= n; i++){ if (s >= 0){ add_tree(root, s, 0, MAXI, lr - i); } if (t[i] < 0){ if (s + t[i] >= 0){ lr = get_tree(root, 0, s + t[i], 0, MAXI) + i; } } else { if (s + t[i] >= 0){ int w = get_tree(root, 0, s + t[i], 0, MAXI); lr = min(1000000, min(w + i, lr)); //printf("aa %d %d\n", i, lr); } } s += t[i]; if (s < 0){ //printf("bebe %d\n", i); lr = 1000000; } } printf("%d\n", lr); }
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 | #include <cstdio> #include <algorithm> using namespace std; #define LL long long #define MAXI 1000000000000000LL struct node { node *left, *right; int result; node(){ left = nullptr; right = nullptr; result = 1000000; } }; node* root = new node(); void add_tree(node* pos, LL s, LL cs, LL ce, int val){ if ((s == cs) && (s == ce)){ pos->result = min(pos->result, val); return; } else if (s <= (cs + ce)/2){ if (pos->left == nullptr){ pos->left = new node(); } add_tree(pos->left, s, cs, (cs + ce)/2, val); } else if (s > (cs + ce)/2){ if (pos->right == nullptr){ pos->right = new node(); } add_tree(pos->right, s, (cs + ce)/2 + 1, ce, val); } if ((pos->left != nullptr) && (pos->right != nullptr)){ pos->result = min(pos->left->result, pos->right->result); } else if (pos->left != nullptr){ pos->result = pos->left->result; } else { pos->result = pos->right->result; } } int get_tree(node* pos, LL s, LL e, LL cs, LL ce){ int def = 1000000; if ((s == cs) && (e == ce)){ if (pos == nullptr){ return def; } else { return pos->result; } } else if ((s <= (cs + ce)/2) && (e <= (cs + ce)/2)){ if (pos->left != nullptr){ return get_tree(pos->left, s, e, cs, (cs + ce)/2); } else { return def; } } else if ((s > (cs + ce)/2) && (e > (cs + ce)/2)){ if (pos->right != nullptr){ return get_tree(pos->right, s, e, (cs + ce)/2 + 1, ce); } else { return def; } } else { int r = def; if (pos->left != nullptr){ r = min(r, get_tree(pos->left, s, (cs + ce)/2, cs, (cs + ce)/2)); } if (pos->right != nullptr){ r = min(r, get_tree(pos->right, (cs + ce)/2 + 1, e, (cs + ce)/2+1, ce)); } return r; } } int t[500005], n; int main(){ scanf("%d", &n); LL tmp = 0; for (int i = 1; i <= n; i++){ scanf("%d", &t[i]); tmp += t[i]; } if (tmp < 0){ printf("-1\n"); return 0; } add_tree(root, 0, 0, MAXI, 0); int lr = 0; LL s = 0; for (int i = 1; i <= n; i++){ if (s >= 0){ add_tree(root, s, 0, MAXI, lr - i); } if (t[i] < 0){ if (s + t[i] >= 0){ lr = get_tree(root, 0, s + t[i], 0, MAXI) + i; } } else { if (s + t[i] >= 0){ int w = get_tree(root, 0, s + t[i], 0, MAXI); lr = min(1000000, min(w + i, lr)); //printf("aa %d %d\n", i, lr); } } s += t[i]; if (s < 0){ //printf("bebe %d\n", i); lr = 1000000; } } printf("%d\n", lr); } |