模板-線段樹
阿新 • • 發佈:2020-11-18
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int N = 1e5 + 10; struct SegmentTree{ int l, r; long long sum, add; }t[N * 4]; int a[N], n, m; void pushup(int p) { t[p].sum = t[p << 1].sum + t[p << 1 | 1].sum; } void build(int p, int l, int r){ t[p].l = l; t[p].r = r; if(l == r){ t[p].sum = a[l]; return; } int mid = l + r >> 1; build(p << 1, l, mid); build (p << 1 | 1, mid + 1, r); pushup(p); } void pushdown(int p) { if(t[p].add) { int ls = p << 1; int rs = p << 1 | 1; t[ls].sum += t[p].add * (t[ls].r - t[ls].l + 1); t[rs].sum += t[p].add * (t[rs].r - t[rs].l + 1); t[ls].add += t[p].add; t[rs].add += t[p].add; t[p].add = 0; } } void change(int p, int l, int r, int d) { if(l <= t[p].l && r >= t[p].r) { t[p].sum += (long long)d * (t[p].r - t[p].l + 1); t[p].add += d; return; } pushdown(p); int mid = t[p].l + t[p].r >> 1; if(l <= mid) change(p << 1, l, r, d); if(r > mid) change(p << 1 | 1, l, r, d); pushup(p); } long long ask(int p, int l, int r) { if(l <= t[p].l && r >= t[p].r) return t[p].sum; pushdown(p); int mid = t[p].l + t[p].r >> 1; long long val = 0; if(l <= mid) val += ask(p << 1, l, r); if(r > mid) val += ask(p << 1 | 1, l, r); return val; } int main() { int n, m; scanf("%d%d", &n, &m); for(int i = 1; i <= n ; i ++) scanf("%d", &a[i]); build(1, 1, n); int op, x, y, k; for(int i = 1; i <= m ; i ++) { scanf("%d%d%d", &op, &x, &y); if(op == 1){ scanf("%d", &k); change(1, x, y, k); } else{ printf("%lld\n", ask(1, x, y)); } } return 0; }