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 123 124 125 126 127 128 129
| #include <bits/stdc++.h> using namespace std; typedef long long ll;
template <typename T> class SegTreeLazyRangeAdd { vector<T> tree, lazy; vector<T> *arr; int n, root, n4, end;
void maintain(int cl, int cr, int p) { int cm = cl + (cr - cl) / 2; if (cl != cr && lazy[p]) { lazy[p * 2] += lazy[p]; lazy[p * 2 + 1] += lazy[p]; tree[p * 2] += lazy[p] * (cm - cl + 1); tree[p * 2 + 1] += lazy[p] * (cr - cm); lazy[p] = 0; } }
T range_sum(int l, int r, int cl, int cr, int p) { if (l <= cl && cr <= r) return tree[p]; int m = cl + (cr - cl) / 2; T sum = 0; maintain(cl, cr, p); if (l <= m) sum += range_sum(l, r, cl, m, p * 2); if (r > m) sum += range_sum(l, r, m + 1, cr, p * 2 + 1); return sum; }
void range_add(int l, int r, T val, int cl, int cr, int p) { if (l <= cl && cr <= r) { lazy[p] += val; tree[p] += (cr - cl + 1) * val; return; } int m = cl + (cr - cl) / 2; maintain(cl, cr, p); if (l <= m) range_add(l, r, val, cl, m, p * 2); if (r > m) range_add(l, r, val, m + 1, cr, p * 2 + 1); tree[p] = tree[p * 2] + tree[p * 2 + 1]; }
void build(int s, int t, int p) { if (s == t) { tree[p] = (*arr)[s]; return; } int m = s + (t - s) / 2; build(s, m, p * 2); build(m + 1, t, p * 2 + 1); tree[p] = tree[p * 2] + tree[p * 2 + 1]; }
public: explicit SegTreeLazyRangeAdd<T>(vector<T> v) { n = v.size(); n4 = n * 4; tree = vector<T>(n4, 0); lazy = vector<T>(n4, 0); arr = &v; end = n - 1; root = 1; build(0, end, 1); arr = nullptr; }
void show(int p, int depth = 0) { if (p > n4 || tree[p] == 0) return; show(p * 2, depth + 1); for (int i = 0; i < depth; ++i) putchar('\t'); printf("%d:%d\n", tree[p], lazy[p]); show(p * 2 + 1, depth + 1); }
T range_sum(int l, int r) { return range_sum(l, r, 0, end, root); }
void range_add(int l, int r, int val) { range_add(l, r, val, 0, end, root); } };
int main() { ll n, m; scanf("%lld%lld", &n, &m); vector<ll> ans; ll x; for (ll i = 0; i < n; i++) { scanf("%lld", &x); ans.push_back(x); } SegTreeLazyRangeAdd<ll> st(ans); for (ll i = 0; i < m; i++) { ll op; scanf("%lld", &op); if (op == 1) { ll x, y, k; scanf("%lld%lld%lld", &x, &y, &k); st.range_add(x - 1, y - 1, k); } else { ll x, y; scanf("%lld %lld", &x, &y); printf("%lld\n", st.range_sum(x - 1, y - 1)); } } return 0; }
|