#include <algorithm> #include <cstdio> #include <set> #include <unordered_map> #include <vector> using namespace std; #define FOR(i,a,b) for(int i=(a);i<(b);++i) #define REP(i,n) FOR(i,0,n) #define VAR(v,w) __typeof(w) v=(w) #define FORE(it,c) for(VAR(it,(c).begin());it!=(c).end();++it) #define ALL(c) (c).begin(),(c).end() #define INT(x) int x; scanf("%d", &x) typedef vector<int> VI; const int mod = 1000000007; int a[300000]; unordered_map<int, int> index; int h, nn, n2; int s[2][1 << 20]; VI offsets; int offset; void add(int i, int v) { int p = offsets[i] & 1; i += n2; s[p][i] = (s[p][i] + v) % mod; i >>= 1; while (i) { REP(q,2) s[q][i] = (s[q][i << 1] + s[q][(i << 1) + 1]) % mod; i >>= 1; } } int get(int x, int y, int p, int node = 1, int level = 0) { if (x >= y) return 0; int start = (node - (1 << level)) << (h - level); int end = start + (1 << (h - level)); if (x == start && y == end) return s[p][node]; int mid = (start + end) >> 1; return (get(x, min(y, mid), p, node << 1, level + 1) + get(max(x, mid), y, p, (node << 1) + 1, level + 1)) % mod; } int getEven() { int x = index[mod - offset]; return (get(0, x, offset & 1) + get(x, nn, !(offset & 1))) % mod; } int main() { INT(n); REP(i,n) scanf("%d", &a[i]); set<int> offsetsSet; offsetsSet.insert(0); int ns = 0; REP(i,n) { ns = (ns + mod - a[i]) % mod; offsetsSet.insert(ns); } offsets = VI(ALL(offsetsSet)); FORE(it,offsetsSet) index[*it] = nn++; index[mod] = nn; h = 0; while ((1 << h) < nn) ++h; n2 = 1 << h; add(0, 1); REP(i,n) { if (i) add(index[(mod - offset) % mod], getEven()); offset = (offset + a[i]) % mod; } printf("%d\n", getEven()); }
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 | #include <algorithm> #include <cstdio> #include <set> #include <unordered_map> #include <vector> using namespace std; #define FOR(i,a,b) for(int i=(a);i<(b);++i) #define REP(i,n) FOR(i,0,n) #define VAR(v,w) __typeof(w) v=(w) #define FORE(it,c) for(VAR(it,(c).begin());it!=(c).end();++it) #define ALL(c) (c).begin(),(c).end() #define INT(x) int x; scanf("%d", &x) typedef vector<int> VI; const int mod = 1000000007; int a[300000]; unordered_map<int, int> index; int h, nn, n2; int s[2][1 << 20]; VI offsets; int offset; void add(int i, int v) { int p = offsets[i] & 1; i += n2; s[p][i] = (s[p][i] + v) % mod; i >>= 1; while (i) { REP(q,2) s[q][i] = (s[q][i << 1] + s[q][(i << 1) + 1]) % mod; i >>= 1; } } int get(int x, int y, int p, int node = 1, int level = 0) { if (x >= y) return 0; int start = (node - (1 << level)) << (h - level); int end = start + (1 << (h - level)); if (x == start && y == end) return s[p][node]; int mid = (start + end) >> 1; return (get(x, min(y, mid), p, node << 1, level + 1) + get(max(x, mid), y, p, (node << 1) + 1, level + 1)) % mod; } int getEven() { int x = index[mod - offset]; return (get(0, x, offset & 1) + get(x, nn, !(offset & 1))) % mod; } int main() { INT(n); REP(i,n) scanf("%d", &a[i]); set<int> offsetsSet; offsetsSet.insert(0); int ns = 0; REP(i,n) { ns = (ns + mod - a[i]) % mod; offsetsSet.insert(ns); } offsets = VI(ALL(offsetsSet)); FORE(it,offsetsSet) index[*it] = nn++; index[mod] = nn; h = 0; while ((1 << h) < nn) ++h; n2 = 1 << h; add(0, 1); REP(i,n) { if (i) add(index[(mod - offset) % mod], getEven()); offset = (offset + a[i]) % mod; } printf("%d\n", getEven()); } |