// Karol Kosinski 2020 #include <cstdio> #define FOR(i,a,b) for(int i=(a);i<(b);++i) //#define DEBUG(x...) printf(x) #define DEBUG(x...) using namespace std; typedef long long LL; constexpr int NX = 5'00'003; constexpr LL INFTY = 1'000'000'000'000'000'001LL; constexpr int R2K(int x) { int r = 1; while (r < x) r <<= 1; return r; } struct Node { LL mx; }; LL to_add; int n2; Node T[R2K(NX) << 1]; inline int parent(int x) { return x >> 1; } inline int left(int x) { return x << 1; } inline int right(int x) { return (x << 1) | 1; } inline void update_all(int v) { to_add += v; }; void insert(int k, LL v) { v -= to_add; int j = n2 + k; while (j > 0) { if (T[j].mx >= v) return; T[j].mx = v; j = parent(j); } } int find_max_key() { if (T[1].mx == -INFTY) { DEBUG("empty\n"); return 0; } DEBUG("to_add: %lld\n", to_add); int j = 1; while (j < n2) { if (T[right(j)].mx + to_add >= 0) j = right(j); else j = left(j); } DEBUG("[%d] %lld\n", j - n2, T[j].mx + to_add); return (T[j].mx + to_add >= 0) ? j - n2 : -1; } void init_tree(int n) { n2 = R2K(n); FOR(i,0,n2) { T[left(i)].mx = -INFTY; T[right(i)].mx = -INFTY; } } int main() { int n, a, counter = 0; scanf("%d", &n); init_tree(n); FOR(i,0,n) { scanf("%d", &a); if (a == 0) { ++ counter; continue; } int k = find_max_key(); update_all(a); DEBUG("(%d / %d)\n", counter, a); if (k != -1) { DEBUG("* (%d / %d)\n", k + counter, a); insert(k + counter, a); } counter = 1; } int res = find_max_key(); printf("%d\n", (res == -1) ? -1 : n - counter - res); 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 | // Karol Kosinski 2020 #include <cstdio> #define FOR(i,a,b) for(int i=(a);i<(b);++i) //#define DEBUG(x...) printf(x) #define DEBUG(x...) using namespace std; typedef long long LL; constexpr int NX = 5'00'003; constexpr LL INFTY = 1'000'000'000'000'000'001LL; constexpr int R2K(int x) { int r = 1; while (r < x) r <<= 1; return r; } struct Node { LL mx; }; LL to_add; int n2; Node T[R2K(NX) << 1]; inline int parent(int x) { return x >> 1; } inline int left(int x) { return x << 1; } inline int right(int x) { return (x << 1) | 1; } inline void update_all(int v) { to_add += v; }; void insert(int k, LL v) { v -= to_add; int j = n2 + k; while (j > 0) { if (T[j].mx >= v) return; T[j].mx = v; j = parent(j); } } int find_max_key() { if (T[1].mx == -INFTY) { DEBUG("empty\n"); return 0; } DEBUG("to_add: %lld\n", to_add); int j = 1; while (j < n2) { if (T[right(j)].mx + to_add >= 0) j = right(j); else j = left(j); } DEBUG("[%d] %lld\n", j - n2, T[j].mx + to_add); return (T[j].mx + to_add >= 0) ? j - n2 : -1; } void init_tree(int n) { n2 = R2K(n); FOR(i,0,n2) { T[left(i)].mx = -INFTY; T[right(i)].mx = -INFTY; } } int main() { int n, a, counter = 0; scanf("%d", &n); init_tree(n); FOR(i,0,n) { scanf("%d", &a); if (a == 0) { ++ counter; continue; } int k = find_max_key(); update_all(a); DEBUG("(%d / %d)\n", counter, a); if (k != -1) { DEBUG("* (%d / %d)\n", k + counter, a); insert(k + counter, a); } counter = 1; } int res = find_max_key(); printf("%d\n", (res == -1) ? -1 : n - counter - res); return 0; } |