Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- const long long mod = 1000000007;
- class Node {
- public:
- long long ans;
- long long sum;
- long long pre;
- long long suf;
- int size;
- Node(long long value) : ans(value), sum(value), pre(value), suf(value), size(1) {}
- Node() : ans(0), sum(0), pre(0), suf(0), size(0) {}
- };
- class SegmentTree {
- private:
- int n;
- vector<Node> tree;
- Node merge(Node nodeLeft, Node nodeRight) {
- Node mergeNode;
- mergeNode.ans = (((nodeRight.size * nodeLeft.suf) % mod) + ((nodeLeft.size * nodeRight.pre) % mod) + ((nodeLeft.ans + nodeRight.ans) % mod)) % mod;
- mergeNode.sum = (nodeLeft.sum + nodeRight.sum) % mod;
- mergeNode.pre = nodeLeft.pre + nodeRight.pre;
- mergeNode.pre += nodeRight.size * nodeLeft.sum;
- mergeNode.suf = nodeLeft.suf + nodeRight.suf;
- mergeNode.suf += nodeLeft.size * nodeRight.sum;
- mergeNode.pre %= mod;
- mergeNode.suf %= mod;
- mergeNode.size = nodeLeft.size + nodeRight.size;
- return mergeNode;
- }
- void build(int node, int start, int end, const vector<long long> &vet) {
- if(start == end) {
- tree[node] = Node(vet[start]);
- return;
- }
- int mid = (start + end) / 2;
- build(2 * node, start, mid, vet);
- build(2 * node + 1, mid + 1, end, vet);
- tree[node] = merge(tree[2 * node], tree[2 * node + 1]);
- }
- Node query(int node, int start, int end, int l, int r) {
- if(start > r or end < l) {
- return Node();
- }
- if(l <= start and end <= r) {
- return tree[node];
- }
- int mid = (start + end) / 2;
- Node queryLeft = query(2 * node, start, mid, l, r);
- Node queryRight = query(2 * node + 1, mid + 1, end, l, r);
- return merge(queryLeft, queryRight);
- }
- void update(int node, int start, int end, int idx, int val) {
- if(start == end) {
- tree[node] = Node((val + tree[node].ans) % mod);
- return;
- }
- int mid = (start + end) / 2;
- if(idx <= mid) {
- update(2 * node, start, mid, idx, val);
- } else {
- update(2 * node + 1, mid + 1, end, idx, val);
- }
- tree[node] = merge(tree[2 * node], tree[2 * node + 1]);
- }
- public:
- void update(int position, int value) {
- update(1, 0, n - 1, position - 1, value);
- }
- long long query(int l, int r) {
- return query(1, 0, n - 1, l - 1, r - 1).ans;
- }
- SegmentTree(const vector<long long> &vet) {
- n = vet.size();
- tree.resize(4 * n);
- build(1, 0, n - 1, vet);
- }
- };
- int32_t main() {
- ios_base::sync_with_stdio(false);
- int n, m;
- cin >> n >> m;
- vector<long long> arr(n);
- for(long long &w : arr)
- cin >> w;
- SegmentTree tree(arr);
- for(int i = 0; i < m; ++i) {
- int o;
- cin >> o;
- if(o == 1) {
- int leftPos;
- int rightPos;
- cin >> leftPos >> rightPos;
- cout << tree.query(leftPos, rightPos) << '\n';
- } else {
- int position;
- int value;
- cin >> position >> value;
- tree.update(position, value);
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement