#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define UI unsigned int
const UI t = 3e5 + 9, p = 1e9 + 7, siz = 2147483648;
LL tab[t], dp[t];
struct Vertex {
UI left, right;
UI sp = 0, sn = 0;
Vertex *left_child = nullptr, *right_child = nullptr;
Vertex(UI lb, UI rb) {
left = lb;
right = rb;
}
void extend() {
if(!left_child && left + 1 < right) {
UI t = (left + right) / 2;
left_child = new Vertex(left, t);
right_child = new Vertex(t, right);
}
}
void add(UI k, UI x) {
if(left + 1 == right) {
if(left % 2) sp = (sp + x) % p;
else sn = (sn + x) % p;
}
else {
extend();
if (left_child) {
if (k < left_child->right)
left_child->add(k, x);
else
right_child->add(k, x);
}
sp = (left_child->sp + right_child->sp) % p;
sn = (left_child->sn + right_child->sn) % p;
}
}
LL get_sum(UI lq, UI rq, int x) {
if(lq <= left && right <= rq) {
if(x == 0) return sp;
else return sn;
}
if(max(left, lq) >= min(right, rq)) return 0;
extend();
return(left_child->get_sum(lq, rq, x) + right_child->get_sum(lq, rq, x)) % p;
}
};
int main() {
std::ios_base::sync_with_stdio(false);
cin.tie(NULL);
int n;
cin >> n;
if(n > 3000) {
Vertex root(0, siz);
root.add(0, 1);
tab[0] = 0;
for(int i = 1; i <= n; i ++) {
LL x;
cin >> x;
tab[i] = tab[i - 1] + x;
}
dp[0] = 1;
for(int i = 1; i <= n; i ++) {
LL l, r;
l = 1 + ((LL) p + 1) * (tab[i] % (2 * p));
l = l % (2 * p);
r = l + p - 1;
dp[i] += root.get_sum(l, min(r + 1, (LL) 2 * p), 0);
if(r >= 2 * p) dp[i] += root.get_sum(0, r % (2 * p) + 1, 0);
l = p + 1 + ((LL) p + 1) * (tab[i] % (2 * p));
l = l % (2 * p);
r = l + p - 1;
dp[i] += root.get_sum(l, min(r + 1, (LL) 2 * p), 1);
if(r >= 2 * p) dp[i] += root.get_sum(0, r % (2 * p) + 1, 1);
dp[i] = dp[i] % p;
root.add(tab[i] % (2 * p), dp[i]);
}
cout << dp[n];
}
else {
tab[0] = 0;
for(int i = 1; i <= n; i ++) {
LL x;
cin >> x;
tab[i] = tab[i - 1] + x;
}
dp[0] = 1;
for(int i = 1; i <= n; i ++) {
for(int k = 0; k < i; k ++) {
if(((tab[i] - tab[k]) % p) % 2 == 0) dp[i] = (dp[i] + dp[k]) % p;
}
}
cout << dp[n];
}
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 | #include <bits/stdc++.h> using namespace std; #define LL long long #define UI unsigned int const UI t = 3e5 + 9, p = 1e9 + 7, siz = 2147483648; LL tab[t], dp[t]; struct Vertex { UI left, right; UI sp = 0, sn = 0; Vertex *left_child = nullptr, *right_child = nullptr; Vertex(UI lb, UI rb) { left = lb; right = rb; } void extend() { if(!left_child && left + 1 < right) { UI t = (left + right) / 2; left_child = new Vertex(left, t); right_child = new Vertex(t, right); } } void add(UI k, UI x) { if(left + 1 == right) { if(left % 2) sp = (sp + x) % p; else sn = (sn + x) % p; } else { extend(); if (left_child) { if (k < left_child->right) left_child->add(k, x); else right_child->add(k, x); } sp = (left_child->sp + right_child->sp) % p; sn = (left_child->sn + right_child->sn) % p; } } LL get_sum(UI lq, UI rq, int x) { if(lq <= left && right <= rq) { if(x == 0) return sp; else return sn; } if(max(left, lq) >= min(right, rq)) return 0; extend(); return(left_child->get_sum(lq, rq, x) + right_child->get_sum(lq, rq, x)) % p; } }; int main() { std::ios_base::sync_with_stdio(false); cin.tie(NULL); int n; cin >> n; if(n > 3000) { Vertex root(0, siz); root.add(0, 1); tab[0] = 0; for(int i = 1; i <= n; i ++) { LL x; cin >> x; tab[i] = tab[i - 1] + x; } dp[0] = 1; for(int i = 1; i <= n; i ++) { LL l, r; l = 1 + ((LL) p + 1) * (tab[i] % (2 * p)); l = l % (2 * p); r = l + p - 1; dp[i] += root.get_sum(l, min(r + 1, (LL) 2 * p), 0); if(r >= 2 * p) dp[i] += root.get_sum(0, r % (2 * p) + 1, 0); l = p + 1 + ((LL) p + 1) * (tab[i] % (2 * p)); l = l % (2 * p); r = l + p - 1; dp[i] += root.get_sum(l, min(r + 1, (LL) 2 * p), 1); if(r >= 2 * p) dp[i] += root.get_sum(0, r % (2 * p) + 1, 1); dp[i] = dp[i] % p; root.add(tab[i] % (2 * p), dp[i]); } cout << dp[n]; } else { tab[0] = 0; for(int i = 1; i <= n; i ++) { LL x; cin >> x; tab[i] = tab[i - 1] + x; } dp[0] = 1; for(int i = 1; i <= n; i ++) { for(int k = 0; k < i; k ++) { if(((tab[i] - tab[k]) % p) % 2 == 0) dp[i] = (dp[i] + dp[k]) % p; } } cout << dp[n]; } return 0; } |
English