#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); } } } |