回归第一章，献给线段树。

# P3372 【模板】线段树 1

#include<bits/stdc++.h>
#define ll long long

using namespace std;

ll ini[400005];
ll n, m;

struct node {
ll sum, mn, mx, laz;
} tr[400005];

ll lc(ll pos) { return (pos << 1); }
ll rc(ll pos) { return ((pos << 1) + 1);}

void update(ll pos) {
tr[pos].sum = tr[lc(pos)].sum + tr[rc(pos)].sum;
tr[pos].mn = min(tr[lc(pos)].mn, tr[rc(pos)].mn);
tr[pos].mx = max(tr[lc(pos)].mx, tr[rc(pos)].mx);
}

void build(ll l ,ll r, ll pos) {
if(l == r) {
tr[pos].sum = ini[l];
tr[pos].mn = ini[l];
tr[pos].mx = ini[l];
return ;
}
ll mid = (l + r) >> 1;
build(l, mid, pos << 1);
build(mid + 1, r, (pos << 1) + 1);
update(pos);
}

void pushdown(ll pos, ll l, ll r) {
if(tr[pos].laz) {
ll mid = (l + r) >> 1;
tr[lc(pos)].laz += tr[pos].laz;
tr[rc(pos)].laz += tr[pos].laz;
tr[lc(pos)].sum += tr[pos].laz * (mid - l + 1);
tr[rc(pos)].sum += tr[pos].laz * (r - mid);
tr[lc(pos)].mn += tr[pos].laz;
tr[lc(pos)].mx += tr[pos].laz;
tr[rc(pos)].mn += tr[pos].laz;
tr[rc(pos)].mx += tr[pos].laz;

tr[pos].laz = 0;
}
}

void add(ll pos, ll l, ll r, ll L, ll R, ll d) {
if(L >= l && R <= r) {
tr[pos].sum += d * (R - L + 1);
tr[pos].laz += d;
tr[pos].mn += d;
tr[pos].mx += d;
return ;
}

pushdown(pos, L, R);

ll mid = (L + R) >> 1;
if(mid >= l)    add(lc(pos), l, r, L, mid, d);
if(mid < r)        add(rc(pos), l, r, mid + 1, R, d);

update(pos);
}

node query(ll pos, ll l, ll r, ll L, ll R) {
if(L >= l && R <= r)
return tr[pos];

pushdown(pos, L, R);

ll mid = (L + R) >> 1; node ans; ans.sum=0,ans.mn=0x7fffffff,ans.mx=-100000000;

if(mid >= l) {
node jq = query(pos << 1, l, r, L, mid);
ans.mn = min(ans.mn, jq.mn);
ans.sum += jq.sum;
ans.mx = max(ans.mx, jq.mx);
}
if(mid < r) {
node jq = query((pos << 1) + 1, l, r, mid + 1, R);
ans.mn = min(ans.mn, jq.mn );
ans.sum += jq.sum;
ans.mx = max(ans.mx, jq.mx);
}

return ans;
}

int main() {
scanf("%lld%lld", &n, &m);
for(int i = 1; i <= n; i ++)
scanf("%lld", &ini[i]);
build(1, n, 1);
for(int i = 1; i <= m; i ++) {
ll x, y, z, s;
scanf("%lld", &s);
if(s == 1)    {
scanf("%lld%lld%lld", &x, &y, &z);
add(1, x, y, 1, n, z);
}
if(s == 2)    {
scanf("%lld%lld", &x, &y);
node ans = query(1, x, y, 1, n);
printf("%lld\n", ans.sum);
}
}
return 0;
}

posted @ 2020-09-04 11:34  Wans_ovo  阅读(134)  评论(0编辑  收藏  举报