#include <iostream> #include <algorithm> #include <vector> #include <unordered_set> #include <unordered_map> using namespace std; #define N 300005 #define MOD 1000000007 long long n; long long a[N]; long long p[N]; long long t[2*N]; unordered_set<int> us; unordered_map<int, int> um; vector<int> vec[2]; int binary_search(int i, int v){ int beg = 0; int end = vec[i].size()-1; int pos = -1; while(beg <= end){ int mid = (beg + end) / 2; if(vec[i][mid] >= v){ end = mid - 1; pos = mid; } else{ beg = mid + 1; } } return pos; } void add(int v, int tl, int tr, int p, int u){ if(tl == tr){ t[v] = (t[v] + u)%MOD; } else{ int tm = (tl+tr)/2; int left = v + 1; int right = v + (tm - tl + 1) * 2; if(p <= tm) add(left, tl, tm, p, u); else add(right, tm+1, tr, p, u); t[v] = (t[left] + t[right]) % MOD; } } long long sum(int v, int tl, int tr, int l, int r){ if(r < l) return 0; else if(tl == l && tr == r){ return t[v]; } else{ int tm = (tl+tr)/2; int left = v + 1; int right = v + (tm - tl + 1) * 2; return (sum(left, tl, tm, l, min(tm, r)) + sum(right, tm+1, tr, max(tm+1, l), r))%MOD; } } int main(){ cin.tie(0); ios_base::sync_with_stdio(0); us.insert(0); vec[0].push_back(0); cin >> n; for(int i=0;i<n;i++){ cin >> a[i]; if(i != 0) p[i] = p[i-1]; p[i] = (p[i] + a[i])%MOD; if(us.count(p[i]) == 0){ us.insert(p[i]); vec[p[i]%2].push_back(p[i]); } } int pos = 0; for(int i=0;i<2;i++){ sort(vec[i].begin(), vec[i].end()); for(int j=0;j<vec[i].size();j++){ um[vec[i][j]] = pos++; } } long long ans = 0; int m = us.size(); add(0, 0, m-1, um[0], 1); for(int i=0;i<n;i++){ ans = 0; if(p[i]%2 == 0){ ans += sum(0, 0, m-1, um[0], um[p[i]]); ans %= MOD; int start_pos = binary_search(1, p[i]); if(start_pos != -1){ ans += sum(0, 0, m-1, um[vec[1][start_pos]], um[vec[1][vec[1].size()-1]]); ans %= MOD; } } else{ ans += sum(0, 0, m-1, um[vec[1][0]], um[p[i]]); ans %= MOD; int start_pos = binary_search(0, p[i]); if(start_pos != -1){ ans += sum(0, 0, m-1, um[vec[0][start_pos]], um[vec[0][vec[0].size()-1]]); ans %= MOD; } } add(0, 0, m-1, um[p[i]], ans); } cout << ans%MOD; 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 129 | #include <iostream> #include <algorithm> #include <vector> #include <unordered_set> #include <unordered_map> using namespace std; #define N 300005 #define MOD 1000000007 long long n; long long a[N]; long long p[N]; long long t[2*N]; unordered_set<int> us; unordered_map<int, int> um; vector<int> vec[2]; int binary_search(int i, int v){ int beg = 0; int end = vec[i].size()-1; int pos = -1; while(beg <= end){ int mid = (beg + end) / 2; if(vec[i][mid] >= v){ end = mid - 1; pos = mid; } else{ beg = mid + 1; } } return pos; } void add(int v, int tl, int tr, int p, int u){ if(tl == tr){ t[v] = (t[v] + u)%MOD; } else{ int tm = (tl+tr)/2; int left = v + 1; int right = v + (tm - tl + 1) * 2; if(p <= tm) add(left, tl, tm, p, u); else add(right, tm+1, tr, p, u); t[v] = (t[left] + t[right]) % MOD; } } long long sum(int v, int tl, int tr, int l, int r){ if(r < l) return 0; else if(tl == l && tr == r){ return t[v]; } else{ int tm = (tl+tr)/2; int left = v + 1; int right = v + (tm - tl + 1) * 2; return (sum(left, tl, tm, l, min(tm, r)) + sum(right, tm+1, tr, max(tm+1, l), r))%MOD; } } int main(){ cin.tie(0); ios_base::sync_with_stdio(0); us.insert(0); vec[0].push_back(0); cin >> n; for(int i=0;i<n;i++){ cin >> a[i]; if(i != 0) p[i] = p[i-1]; p[i] = (p[i] + a[i])%MOD; if(us.count(p[i]) == 0){ us.insert(p[i]); vec[p[i]%2].push_back(p[i]); } } int pos = 0; for(int i=0;i<2;i++){ sort(vec[i].begin(), vec[i].end()); for(int j=0;j<vec[i].size();j++){ um[vec[i][j]] = pos++; } } long long ans = 0; int m = us.size(); add(0, 0, m-1, um[0], 1); for(int i=0;i<n;i++){ ans = 0; if(p[i]%2 == 0){ ans += sum(0, 0, m-1, um[0], um[p[i]]); ans %= MOD; int start_pos = binary_search(1, p[i]); if(start_pos != -1){ ans += sum(0, 0, m-1, um[vec[1][start_pos]], um[vec[1][vec[1].size()-1]]); ans %= MOD; } } else{ ans += sum(0, 0, m-1, um[vec[1][0]], um[p[i]]); ans %= MOD; int start_pos = binary_search(0, p[i]); if(start_pos != -1){ ans += sum(0, 0, m-1, um[vec[0][start_pos]], um[vec[0][vec[0].size()-1]]); ans %= MOD; } } add(0, 0, m-1, um[p[i]], ans); } cout << ans%MOD; return 0; } |