#include <bits/stdc++.h> using namespace std; const int MOD = 1e9 + 7; const int MAX_N = 3e5 + 10; #define AGREE 0 #define DISAGREE 1 int n; int a[MAX_N]; vector<int> sums; unordered_map<int, int> order; int possible[2][MAX_N]; inline void add_mod(int &a, int b) { a = (a + b) % MOD; } void add_result(int sum, int result) { int tab = sum % 2; int pos = order[sum]; while (pos < MAX_N) { add_mod(possible[tab][pos], result); pos += (pos & (-pos)); } } int get_upto(int agree, int sum) { int tab = (sum % 2) ^ agree; int pos = order[sum]; int result = 0; while (pos > 0) { add_mod(result, possible[tab][pos]); pos -= (pos & (-pos)); } return result; } int get_gthan(int agree, int sum) { int result = get_upto(agree, MOD + 1 - (sum % 2)) // preserve parity - get_upto(agree, sum); if (result < 0) result += MOD; return result; } void get_sums() { int sum = 0; sums.push_back(0); for (int i = n-1; i >= 0; i--) { add_mod(sum, a[i]); sums.push_back(sum); } } void get_order(vector<int> &sums) { sort(sums.begin(), sums.end()); auto last = std::unique(sums.begin(), sums.end()); sums.erase(last, sums.end()); for (int j = 0; j < sums.size(); j++) order[sums[j]] = j + 1; order[MOD] = sums.size() + 1; // watchman 1 order[MOD + 1] = sums.size() + 2; // watchman 2 } int get_result() { int sum = 0; int loc_result; for (int i = n-1; i >= 0; i--) { add_mod(sum, a[i]); loc_result = 0; add_mod(loc_result, get_upto(AGREE, sum)); add_mod(loc_result, get_gthan(DISAGREE, sum)); add_result(sum, loc_result); } return loc_result; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cin >> n; for (int i = 0; i < n; i++) cin >> a[i]; get_sums(); get_order(sums); add_result(0, 1); cout << get_result() << endl; 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 | #include <bits/stdc++.h> using namespace std; const int MOD = 1e9 + 7; const int MAX_N = 3e5 + 10; #define AGREE 0 #define DISAGREE 1 int n; int a[MAX_N]; vector<int> sums; unordered_map<int, int> order; int possible[2][MAX_N]; inline void add_mod(int &a, int b) { a = (a + b) % MOD; } void add_result(int sum, int result) { int tab = sum % 2; int pos = order[sum]; while (pos < MAX_N) { add_mod(possible[tab][pos], result); pos += (pos & (-pos)); } } int get_upto(int agree, int sum) { int tab = (sum % 2) ^ agree; int pos = order[sum]; int result = 0; while (pos > 0) { add_mod(result, possible[tab][pos]); pos -= (pos & (-pos)); } return result; } int get_gthan(int agree, int sum) { int result = get_upto(agree, MOD + 1 - (sum % 2)) // preserve parity - get_upto(agree, sum); if (result < 0) result += MOD; return result; } void get_sums() { int sum = 0; sums.push_back(0); for (int i = n-1; i >= 0; i--) { add_mod(sum, a[i]); sums.push_back(sum); } } void get_order(vector<int> &sums) { sort(sums.begin(), sums.end()); auto last = std::unique(sums.begin(), sums.end()); sums.erase(last, sums.end()); for (int j = 0; j < sums.size(); j++) order[sums[j]] = j + 1; order[MOD] = sums.size() + 1; // watchman 1 order[MOD + 1] = sums.size() + 2; // watchman 2 } int get_result() { int sum = 0; int loc_result; for (int i = n-1; i >= 0; i--) { add_mod(sum, a[i]); loc_result = 0; add_mod(loc_result, get_upto(AGREE, sum)); add_mod(loc_result, get_gthan(DISAGREE, sum)); add_result(sum, loc_result); } return loc_result; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cin >> n; for (int i = 0; i < n; i++) cin >> a[i]; get_sums(); get_order(sums); add_result(0, 1); cout << get_result() << endl; return 0; } |