#include <bits/stdc++.h>
using namespace std;
constexpr int P = 1000*1000*1000 + 7;
struct V
{
int v[2];
int& operator[](int i) { return v[i]; }
void Adjust(int x) {
x &= 1;
tie(v[0], v[1]) = make_tuple(v[x], v[x ^ 1]);
}
};
struct Node
{
Node *left, *right;
int pri;
int delta;
V count, total;
Node(Node *left, Node *right, int pri, int x, V count)
: left(left), right(right), pri(pri), delta(x), count(count) { Update(); }
void Update() {
total = count;
for (int i = 0; i < 2; ++i) {
int j = i ^ (delta & 1);
if (left) total[i] = (total[i] + left->total[j]) % P;
if (right) total[i] = (total[i] + right->total[j]) % P;
}
}
};
class Tree
{
typedef Node* Ptr;
Ptr root = nullptr;
Ptr Shift(Ptr v, int x) {
if (v) {
v->delta += x;
v->count.Adjust(x);
v->total.Adjust(x);
}
return v;
}
Ptr Merge(Ptr a, Ptr b) {
if (!a) return b;
if (!b) return a;
if (a->pri < b->pri) {
a->right = Merge(a->right, Shift(b, -a->delta));
a->Update();
return a;
} else {
b->left = Merge(Shift(a, -b->delta), b->left);
b->Update();
return b;
}
}
pair<Ptr, Ptr> Split(Ptr v, int x)
{
if (!v) return pair<Ptr, Ptr>(nullptr, nullptr);
if (x <= v->delta) {
auto l = Split(v->left, x - v->delta);
v->left = l.second;
v->Update();
return make_pair(Shift(l.first, v->delta), v);
} else {
auto r = Split(v->right, x - v->delta);
v->right = r.first;
v->Update();
return make_pair(v, Shift(r.second, v->delta));
}
}
void Add(Ptr& v, int pri, int x, V count)
{
if (v && pri >= v->pri) {
count.Adjust(v->delta);
Add(x < v->delta ? v->left : v->right, pri, x - v->delta, count);
v->Update();
} else {
auto s = Split(v, x);
v = new Node(Shift(s.first, -x), Shift(s.second, -x), pri, x, count);
}
}
public:
void Add(int x, V count) { Add(root, rand(), x, count); }
V Count() { return root->total; }
void Shift(int x) {
if (x == 0) return;
auto s = Split(root, P - x);
Shift(s.first, x);
Shift(s.second, x - P);
root = Merge(s.second, s.first);
}
};
int main()
{
int n;
scanf("%d", &n);
Tree tree;
V count{{1, 0}};
tree.Add(0, count);
for (; n > 0; --n) {
int x;
scanf("%d", &x);
tree.Shift(x);
count = tree.Count();
count[1] = 0;
tree.Add(0, count);
}
printf("%d\n", count[0]);
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 | #include <bits/stdc++.h> using namespace std; constexpr int P = 1000*1000*1000 + 7; struct V { int v[2]; int& operator[](int i) { return v[i]; } void Adjust(int x) { x &= 1; tie(v[0], v[1]) = make_tuple(v[x], v[x ^ 1]); } }; struct Node { Node *left, *right; int pri; int delta; V count, total; Node(Node *left, Node *right, int pri, int x, V count) : left(left), right(right), pri(pri), delta(x), count(count) { Update(); } void Update() { total = count; for (int i = 0; i < 2; ++i) { int j = i ^ (delta & 1); if (left) total[i] = (total[i] + left->total[j]) % P; if (right) total[i] = (total[i] + right->total[j]) % P; } } }; class Tree { typedef Node* Ptr; Ptr root = nullptr; Ptr Shift(Ptr v, int x) { if (v) { v->delta += x; v->count.Adjust(x); v->total.Adjust(x); } return v; } Ptr Merge(Ptr a, Ptr b) { if (!a) return b; if (!b) return a; if (a->pri < b->pri) { a->right = Merge(a->right, Shift(b, -a->delta)); a->Update(); return a; } else { b->left = Merge(Shift(a, -b->delta), b->left); b->Update(); return b; } } pair<Ptr, Ptr> Split(Ptr v, int x) { if (!v) return pair<Ptr, Ptr>(nullptr, nullptr); if (x <= v->delta) { auto l = Split(v->left, x - v->delta); v->left = l.second; v->Update(); return make_pair(Shift(l.first, v->delta), v); } else { auto r = Split(v->right, x - v->delta); v->right = r.first; v->Update(); return make_pair(v, Shift(r.second, v->delta)); } } void Add(Ptr& v, int pri, int x, V count) { if (v && pri >= v->pri) { count.Adjust(v->delta); Add(x < v->delta ? v->left : v->right, pri, x - v->delta, count); v->Update(); } else { auto s = Split(v, x); v = new Node(Shift(s.first, -x), Shift(s.second, -x), pri, x, count); } } public: void Add(int x, V count) { Add(root, rand(), x, count); } V Count() { return root->total; } void Shift(int x) { if (x == 0) return; auto s = Split(root, P - x); Shift(s.first, x); Shift(s.second, x - P); root = Merge(s.second, s.first); } }; int main() { int n; scanf("%d", &n); Tree tree; V count{{1, 0}}; tree.Add(0, count); for (; n > 0; --n) { int x; scanf("%d", &x); tree.Shift(x); count = tree.Count(); count[1] = 0; tree.Add(0, count); } printf("%d\n", count[0]); return 0; } |
English