Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <algorithm>
- #include <iostream>
- #include <numeric>
- #include <cassert>
- #include <vector>
- typedef long long llong;
- const int MAXN = 100000 + 10;
- const llong INF = 1e18;
- const int INTINF = 1e9;
- int n, q;
- struct SegmentTree
- {
- struct Node
- {
- llong sum;
- int min, max;
- llong lazy;
- Node()
- {
- sum = lazy = 0;
- min = INTINF;
- max = 0;
- }
- };
- Node tree[4*MAXN];
- Node combine(Node left, Node right)
- {
- Node res;
- res.sum = left.sum + right.sum;
- res.min = std::min(left.min, right.min);
- res.max = std::max(left.max, right.max);
- return res;
- }
- void push(int node, int l, int r)
- {
- if (tree[node].lazy == 0)
- {
- return;
- }
- tree[node].sum += tree[node].lazy * (r - l + 1);
- tree[node].min += tree[node].lazy;
- tree[node].max += tree[node].lazy;
- if (l < r)
- {
- tree[2*node].lazy += tree[node].lazy;
- tree[2*node + 1].lazy += tree[node].lazy;
- }
- tree[node].lazy = 0;
- }
- void build(int l, int r, int node, int a[])
- {
- if (l == r)
- {
- tree[node].sum = tree[node].min = tree[node].max = a[l];
- return;
- }
- int mid = (l + r) / 2;
- build(l, mid, 2*node, a);
- build(mid + 1, r, 2*node + 1, a);
- tree[node] = combine(tree[2*node], tree[2*node + 1]);
- }
- void update(int l, int r, int node, int queryL, int queryR, int queryVal)
- {
- push(node, l, r);
- if (queryR < l || r < queryL)
- {
- return;
- }
- if (queryL <= l && r <= queryR)
- {
- tree[node].lazy += queryVal;
- push(node, l, r);
- return;
- }
- int mid = (l + r) / 2;
- update(l, mid, 2*node, queryL, queryR, queryVal);
- update(mid + 1, r, 2*node + 1, queryL, queryR, queryVal);
- tree[node] = combine(tree[2*node], tree[2*node + 1]);
- }
- Node query(int l, int r, int node, int queryL, int queryR)
- {
- if (queryL <= l && r <= queryR)
- {
- return tree[node];
- }
- Node res;
- int mid = (l + r) / 2;
- if (queryL <= mid) res = combine(res, query(l, mid, 2*node, queryL, queryR));
- if (mid + 1 <= queryR) res = combine(res, query(mid + 1, r, 2*node + 1, queryL, queryR));
- return res;
- }
- void build(int a[])
- {
- build(1, n, 1, a);
- }
- void update(int l, int r, int val)
- {
- update(1, n, 1, l, r, val);
- }
- Node query(int l, int r)
- {
- return query(1, n, 1, l, r);
- }
- };
- int a[MAXN];
- SegmentTree tree;
- void solve()
- {
- tree.build(a);
- for (int i = 1 ; i <= q ; ++i)
- {
- char qType;
- int l, r;
- std::cin >> qType >> l >> r;
- if (qType == '+')
- {
- int val;
- std::cin >> val;
- tree.update(l, r, val);
- } else if (qType == '?')
- {
- SegmentTree::Node res = tree.query(l, r);
- std::cout << res.sum << ' ' << res.min << ' ' << res.max << '\n';
- } else
- {
- assert(false);
- }
- }
- }
- void input()
- {
- std::cin >> n >> q;
- for (int i = 1 ; i <= n ; ++i)
- {
- std::cin >> a[i];
- }
- }
- void fastIOI()
- {
- std::ios_base :: sync_with_stdio(0);
- std::cout.tie(nullptr);
- std::cin.tie(nullptr);
- }
- int main()
- {
- fastIOI();
- input();
- solve();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement