#include <bits/stdc++.h> #define FOR(i, n) for(int i = 0; i < (n); ++i) #define REP(i, a, b) for(int i = (a); i < (b); ++i) #define TRAV(i, a) for(auto & i : (a)) #define SZ(x) ((int)(x).size()) #define X first #define Y second #define PR std::pair #define MP std::make_pair typedef long long ll; typedef std::pair<int, int> PII; typedef std::vector<int> VI; constexpr int MOD = 1000000007; constexpr int M2 = 2*MOD; inline int ADD(unsigned a, unsigned b){ // TODO: int i sprawdzic czy daje WA return (a + b >= M2 ? a + b - M2 : a + b); } inline int SUB(unsigned a, unsigned b){ // TODO: int i sprawdzic czy daje WA return (a >= b ? a - b : M2 + a - b); } struct BIT{ VI t; inline int LSB(int a){ return a&(-a); } BIT(){} BIT(int sz){ t.resize(sz+1); } void add(int x, int val){ x++; while(x < SZ(t)) t[x] = (t[x] + val) % MOD, x += LSB(x); } int query(int x){ x++; int r = 0; while(x > 0) r = (r + t[x]) % MOD, x -= LSB(x); return r; } }; struct Tree{ BIT bit; VI vals; int kto(int a){ return (int)(std::lower_bound(vals.begin(), vals.end(), a) - vals.begin()); } void init(VI A){ vals = std::move(A); std::sort(vals.begin(), vals.end()); vals.resize(std::unique(vals.begin(), vals.end()) - vals.begin()); bit = BIT(SZ(vals) + 4); } void add(int v, int val){ int co = kto(v); assert(vals[co] == v); bit.add(co, val); } int query(int a, int b){ int from = kto(a); int to = kto(b+1)-1; if(from > to) return 0; int ret = (bit.query(to) - (from == 0 ? 0 : bit.query(from - 1)))%MOD; if(ret < 0) ret += MOD; return ret; } }; std::vector<PR<ll, int>> byly; std::vector<Tree> t; void init(VI pref){ t.resize(2); FOR(i, 2) t[i].init(pref); t[0].add(0, 1); } int add(int p){ int ans = 0; FOR(par, 2){ int ind = (p % 2) ^ par; auto& tre = t[ind]; int from = MOD * par; int to = from + MOD - 1; from = SUB(from, p); to = SUB(to, p); int l = (M2 - to)%M2; int r = (M2 - from)%M2; if(l < r){ ans = (ans + tre.query(l, r))%MOD; }else{ ans = (1ll * ans + tre.query(l, M2-1) + tre.query(0, r)) % MOD; } } t[p%2].add(p, ans); return ans; } int main() { std::ios_base::sync_with_stdio(false); std::cin.tie(0); int n; std::cin >> n; VI A(n); FOR(i, n) std::cin >> A[i]; VI pref; pref.push_back(0); TRAV(i, A) pref.push_back(ADD(pref.back(), i)); init(pref); int sum = 0; FOR(i, n){ sum = ADD(sum, A[i]); if(i == n-1) std::cout << add(sum) << "\n"; else add(sum); } 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 120 121 122 123 124 125 126 127 128 | #include <bits/stdc++.h> #define FOR(i, n) for(int i = 0; i < (n); ++i) #define REP(i, a, b) for(int i = (a); i < (b); ++i) #define TRAV(i, a) for(auto & i : (a)) #define SZ(x) ((int)(x).size()) #define X first #define Y second #define PR std::pair #define MP std::make_pair typedef long long ll; typedef std::pair<int, int> PII; typedef std::vector<int> VI; constexpr int MOD = 1000000007; constexpr int M2 = 2*MOD; inline int ADD(unsigned a, unsigned b){ // TODO: int i sprawdzic czy daje WA return (a + b >= M2 ? a + b - M2 : a + b); } inline int SUB(unsigned a, unsigned b){ // TODO: int i sprawdzic czy daje WA return (a >= b ? a - b : M2 + a - b); } struct BIT{ VI t; inline int LSB(int a){ return a&(-a); } BIT(){} BIT(int sz){ t.resize(sz+1); } void add(int x, int val){ x++; while(x < SZ(t)) t[x] = (t[x] + val) % MOD, x += LSB(x); } int query(int x){ x++; int r = 0; while(x > 0) r = (r + t[x]) % MOD, x -= LSB(x); return r; } }; struct Tree{ BIT bit; VI vals; int kto(int a){ return (int)(std::lower_bound(vals.begin(), vals.end(), a) - vals.begin()); } void init(VI A){ vals = std::move(A); std::sort(vals.begin(), vals.end()); vals.resize(std::unique(vals.begin(), vals.end()) - vals.begin()); bit = BIT(SZ(vals) + 4); } void add(int v, int val){ int co = kto(v); assert(vals[co] == v); bit.add(co, val); } int query(int a, int b){ int from = kto(a); int to = kto(b+1)-1; if(from > to) return 0; int ret = (bit.query(to) - (from == 0 ? 0 : bit.query(from - 1)))%MOD; if(ret < 0) ret += MOD; return ret; } }; std::vector<PR<ll, int>> byly; std::vector<Tree> t; void init(VI pref){ t.resize(2); FOR(i, 2) t[i].init(pref); t[0].add(0, 1); } int add(int p){ int ans = 0; FOR(par, 2){ int ind = (p % 2) ^ par; auto& tre = t[ind]; int from = MOD * par; int to = from + MOD - 1; from = SUB(from, p); to = SUB(to, p); int l = (M2 - to)%M2; int r = (M2 - from)%M2; if(l < r){ ans = (ans + tre.query(l, r))%MOD; }else{ ans = (1ll * ans + tre.query(l, M2-1) + tre.query(0, r)) % MOD; } } t[p%2].add(p, ans); return ans; } int main() { std::ios_base::sync_with_stdio(false); std::cin.tie(0); int n; std::cin >> n; VI A(n); FOR(i, n) std::cin >> A[i]; VI pref; pref.push_back(0); TRAV(i, A) pref.push_back(ADD(pref.back(), i)); init(pref); int sum = 0; FOR(i, n){ sum = ADD(sum, A[i]); if(i == n-1) std::cout << add(sum) << "\n"; else add(sum); } return 0; } |