#include <cstdio>
#include <algorithm>
#define MOD 1000000007ll
#define TREE_SIZE 2147483648ll
using namespace std;
typedef long long LL;
class Node {
public:
Node* left;
Node* right;
LL parSum;
LL nParSum;
LL leftBorder;
LL rightBorder;
Node(LL l, LL r) {
this->left = NULL;
this->right = NULL;
this->parSum = 0;
this->nParSum = 0;
this->leftBorder = l;
this->rightBorder = r;
}
};
Node* tree = NULL;
LL sum(LL l, LL r, Node* node, bool takePar) {
if (l > r) {
return 0;
}
if (node->leftBorder == l && node->rightBorder == r) {
return takePar ? node->parSum : node->nParSum;
} else {
LL ret = 0;
if (node->left && l <= node->left->rightBorder) {
ret += sum(l, min(node->left->rightBorder, r), node->left, takePar);
}
if (node->right && r >= node->right->leftBorder) {
ret += sum(max(node->right->leftBorder, l), r, node->right, takePar);
}
return ret % MOD;
}
}
void add(LL pos, Node* node, LL amount) {
if (pos % 2 == 0) {
node->parSum = (node->parSum + amount) % MOD;
} else {
node->nParSum = (node->nParSum + amount) % MOD;
}
LL mid = (node->leftBorder + node->rightBorder) >> 1;
if (node->leftBorder == node->rightBorder) {
return;
}
if (pos <= mid) {
if (node->left == NULL) {
node->left = new Node(node->leftBorder, mid);
}
add(pos, node->left, amount);
} else {
if (node->right == NULL) {
node->right = new Node(mid + 1, node->rightBorder);
}
add(pos, node->right, amount);
}
}
int main() {
tree = new Node(0, TREE_SIZE - 1);
LL prefSum = 0, x = 0;
int n = 0;
scanf("%d", &n);
add(0, tree, 1);
for (int i = 0; i < n; i++) {
scanf("%lld", &x);
prefSum = (prefSum + x) % (2 * MOD);
LL ile = 0;
if (prefSum < MOD) {
ile += sum(0, prefSum, tree, prefSum % 2 == 0);
ile += sum(prefSum + 1, prefSum + MOD, tree,prefSum % 2 == 1);
ile += sum(prefSum + MOD + 1, 2 * MOD - 1, tree, prefSum % 2 == 0);
} else {
ile += sum(prefSum - MOD + 1, prefSum, tree, prefSum % 2 == 0);
ile += sum(0, prefSum - MOD, tree, prefSum % 2 == 1);
ile += sum(prefSum + 1, 2 * MOD - 1, tree, prefSum % 2 == 1);
}
ile = ile % MOD;
add(prefSum, tree, ile);
if (i == n - 1) {
printf("%lld\n", ile);
}
}
}
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 | #include <cstdio> #include <algorithm> #define MOD 1000000007ll #define TREE_SIZE 2147483648ll using namespace std; typedef long long LL; class Node { public: Node* left; Node* right; LL parSum; LL nParSum; LL leftBorder; LL rightBorder; Node(LL l, LL r) { this->left = NULL; this->right = NULL; this->parSum = 0; this->nParSum = 0; this->leftBorder = l; this->rightBorder = r; } }; Node* tree = NULL; LL sum(LL l, LL r, Node* node, bool takePar) { if (l > r) { return 0; } if (node->leftBorder == l && node->rightBorder == r) { return takePar ? node->parSum : node->nParSum; } else { LL ret = 0; if (node->left && l <= node->left->rightBorder) { ret += sum(l, min(node->left->rightBorder, r), node->left, takePar); } if (node->right && r >= node->right->leftBorder) { ret += sum(max(node->right->leftBorder, l), r, node->right, takePar); } return ret % MOD; } } void add(LL pos, Node* node, LL amount) { if (pos % 2 == 0) { node->parSum = (node->parSum + amount) % MOD; } else { node->nParSum = (node->nParSum + amount) % MOD; } LL mid = (node->leftBorder + node->rightBorder) >> 1; if (node->leftBorder == node->rightBorder) { return; } if (pos <= mid) { if (node->left == NULL) { node->left = new Node(node->leftBorder, mid); } add(pos, node->left, amount); } else { if (node->right == NULL) { node->right = new Node(mid + 1, node->rightBorder); } add(pos, node->right, amount); } } int main() { tree = new Node(0, TREE_SIZE - 1); LL prefSum = 0, x = 0; int n = 0; scanf("%d", &n); add(0, tree, 1); for (int i = 0; i < n; i++) { scanf("%lld", &x); prefSum = (prefSum + x) % (2 * MOD); LL ile = 0; if (prefSum < MOD) { ile += sum(0, prefSum, tree, prefSum % 2 == 0); ile += sum(prefSum + 1, prefSum + MOD, tree,prefSum % 2 == 1); ile += sum(prefSum + MOD + 1, 2 * MOD - 1, tree, prefSum % 2 == 0); } else { ile += sum(prefSum - MOD + 1, prefSum, tree, prefSum % 2 == 0); ile += sum(0, prefSum - MOD, tree, prefSum % 2 == 1); ile += sum(prefSum + 1, 2 * MOD - 1, tree, prefSum % 2 == 1); } ile = ile % MOD; add(prefSum, tree, ile); if (i == n - 1) { printf("%lld\n", ile); } } } |
English