【模板】线段树维护区间和、最大最小值

俺回归复建辣!!!

这两天还是挺绝望的,曾经随手能打的线段树调了两天硬是卡不过洛谷,于是只好换了种方法写。

很多东西都记不得了,但幸好大一不上专业课可以慢慢捡回来一点。

没有人陪着一起打代码真的好孤单....真的想你们了。

了解到大家天南地北但是很多都进入了计算机软件信息之类的专业,说不定以后还可以多交流呢!大家要加油呀,在acm赛场再见!(也许呢)


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

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;
}

还是我的代码风格!(丑),复制了以前提交记录的main部分终于a掉了。

感谢洛谷有提交记录,感谢我以前写的blog,让u盘坏掉又丢失后一切还有迹可循。

下午去找$Abyssful$一起打代码辣。开心。

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