#include <iostream> #include <algorithm> #include <map> using namespace std; #define DF(x) #define D(x) #define MAX 524288 //#define MAX 8 #define N 1000000007 int n,n2; typedef long long ll; ll P[MAX]; ll S[MAX]; int in[MAX]; int v[MAX]; map<int,int> _map; void print_v(auto *v, int s, int n, const char *str = "v: "){ printf(str); for(int i=s;i<n;i++) printf("%lld ", v[i]); printf("--\n"); } ll NN(ll x) { if (x >= N) return x - N; return x ; } struct Tree { ll p,n; Tree invert() { return {n,p}; } }; Tree operator+(const Tree a, const Tree b) { return {.p = NN(a.p + b.p), .n = NN(a.n + b.n)}; } Tree tree[MAX*2]; void print_t() { int j = 2; for (int i=1;i<MAX*2;i++) { if (i == j) { printf("\n"); j*=2; } printf("(%lld,%lld) ", tree[i].p, tree[i].n); } printf("\n"); for(int i=0;i<n2;i++) { printf("%lld ", v[i]); } printf("\n"); } void tree_update(int pos) { if (pos < 1) return; tree[pos]= tree[2*pos] + tree[2*pos+1]; return tree_update(pos/2); } Tree _tree_find(int x, int y, int a, int b, int pos, int tabs = 0) { int ab = (a+b)/2; Tree r; DF(for(int i=0;i<1*tabs;i++) printf(" "); printf("find: [%d - %d) , [%d - %d - %d), pos: %d\n", x,y,a, ab,b,pos); ) if( y <= a || b <= x || y<=x) { r = {0,0}; } else if (x <= a && b <= y) { r = tree[pos]; } else r = _tree_find(x, y, a, ab, 2*pos,tabs+1) + _tree_find(x, y, ab, b, 2*pos+1, tabs+1); DF(for(int i=0;i<1*tabs;i++) printf(" "); printf("result: (%d,%d)\n",r.p,r.n);) return r; } int main() { cin >> n; for(int i=1;i<=n;i++) cin >> in[i]; for(int i=1;i<=n;i++) S[i] = NN(S[i-1] + in[i]); for(int i=0;i<=n;i++) v[i] = NN(N-S[i]); D(print_v(in, 1, n+1, "in: ")); D(print_v(S , 0, n+1, "S: ")); D(print_v(v, 0, n+1)); sort(v,v+n+1); int *vend = unique(v, v+n+1); n2= distance(v, vend); for(int i=0;i<n2;i++) _map.emplace(v[i], i); D(print_v(v, 0, n2)); Tree v, l,h; tree[0+MAX] = tree[0+MAX] + Tree{1,0}; tree_update((0+MAX)/2); D(print_t()); for(int i=1;i<=n;i++) { int si = NN(N - S[i]); int pos = _map[si]; D(printf("-------- Add: %d (si: %d pos: %d)\n",in[i], si, pos)); int zero = pos; D(printf("zero pos: %d\n", zero)); l = _tree_find(0, zero, 0, MAX, 1); h = _tree_find(zero, MAX, 0, MAX, 1).invert(); if (S[i] & 1) { l = l.invert(); h = h.invert(); } v = h+l; v.n = 0; D(printf("l:(%d,%d) h:(%d,%d) \n",l.p,l.n,h.p,h.n)); if (si & 1) v = v.invert(); D(printf("Adding new element to tree in: %lld (%lld,%lld)\n", in[i],v.p,v.n)); tree[pos+MAX] = tree[pos+MAX] + v; tree_update((pos+MAX)/2); D(print_t()); if (si & 1) v = v.invert(); } cout << v.p << "\n"; }
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 126 127 128 129 130 131 132 | #include <iostream> #include <algorithm> #include <map> using namespace std; #define DF(x) #define D(x) #define MAX 524288 //#define MAX 8 #define N 1000000007 int n,n2; typedef long long ll; ll P[MAX]; ll S[MAX]; int in[MAX]; int v[MAX]; map<int,int> _map; void print_v(auto *v, int s, int n, const char *str = "v: "){ printf(str); for(int i=s;i<n;i++) printf("%lld ", v[i]); printf("--\n"); } ll NN(ll x) { if (x >= N) return x - N; return x ; } struct Tree { ll p,n; Tree invert() { return {n,p}; } }; Tree operator+(const Tree a, const Tree b) { return {.p = NN(a.p + b.p), .n = NN(a.n + b.n)}; } Tree tree[MAX*2]; void print_t() { int j = 2; for (int i=1;i<MAX*2;i++) { if (i == j) { printf("\n"); j*=2; } printf("(%lld,%lld) ", tree[i].p, tree[i].n); } printf("\n"); for(int i=0;i<n2;i++) { printf("%lld ", v[i]); } printf("\n"); } void tree_update(int pos) { if (pos < 1) return; tree[pos]= tree[2*pos] + tree[2*pos+1]; return tree_update(pos/2); } Tree _tree_find(int x, int y, int a, int b, int pos, int tabs = 0) { int ab = (a+b)/2; Tree r; DF(for(int i=0;i<1*tabs;i++) printf(" "); printf("find: [%d - %d) , [%d - %d - %d), pos: %d\n", x,y,a, ab,b,pos); ) if( y <= a || b <= x || y<=x) { r = {0,0}; } else if (x <= a && b <= y) { r = tree[pos]; } else r = _tree_find(x, y, a, ab, 2*pos,tabs+1) + _tree_find(x, y, ab, b, 2*pos+1, tabs+1); DF(for(int i=0;i<1*tabs;i++) printf(" "); printf("result: (%d,%d)\n",r.p,r.n);) return r; } int main() { cin >> n; for(int i=1;i<=n;i++) cin >> in[i]; for(int i=1;i<=n;i++) S[i] = NN(S[i-1] + in[i]); for(int i=0;i<=n;i++) v[i] = NN(N-S[i]); D(print_v(in, 1, n+1, "in: ")); D(print_v(S , 0, n+1, "S: ")); D(print_v(v, 0, n+1)); sort(v,v+n+1); int *vend = unique(v, v+n+1); n2= distance(v, vend); for(int i=0;i<n2;i++) _map.emplace(v[i], i); D(print_v(v, 0, n2)); Tree v, l,h; tree[0+MAX] = tree[0+MAX] + Tree{1,0}; tree_update((0+MAX)/2); D(print_t()); for(int i=1;i<=n;i++) { int si = NN(N - S[i]); int pos = _map[si]; D(printf("-------- Add: %d (si: %d pos: %d)\n",in[i], si, pos)); int zero = pos; D(printf("zero pos: %d\n", zero)); l = _tree_find(0, zero, 0, MAX, 1); h = _tree_find(zero, MAX, 0, MAX, 1).invert(); if (S[i] & 1) { l = l.invert(); h = h.invert(); } v = h+l; v.n = 0; D(printf("l:(%d,%d) h:(%d,%d) \n",l.p,l.n,h.p,h.n)); if (si & 1) v = v.invert(); D(printf("Adding new element to tree in: %lld (%lld,%lld)\n", in[i],v.p,v.n)); tree[pos+MAX] = tree[pos+MAX] + v; tree_update((pos+MAX)/2); D(print_t()); if (si & 1) v = v.invert(); } cout << v.p << "\n"; } |