“线段树区间最大值”
  • 板块学术版
  • 楼主_Kouki_
  • 当前回复6
  • 已保存回复6
  • 发布时间2022/7/6 20:37
  • 上次更新2023/10/27 21:41:34
查看原帖
“线段树区间最大值”
364847
_Kouki_楼主2022/7/6 20:37

这是我的线段树代码,没注释见谅,功能是”区间加+区间和(lazy优化)“但我又需要“区间最大值”应当如何修改。希望dalao可以指出修改的地方。感谢!

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef double db;

const int N=4*1e5+50;

ll a[N],ans[N],lazy_add[N];

ll ls(ll x){return x<<1;}
ll rs(ll x){return x<<1|1;}
void push_up(ll p){ans[p]=ans[ls(p)]+ans[rs(p)];}
void build(ll p,ll l,ll r){
    lazy_add[p]=0;
    if(l==r) {ans[p]=a[l];return;}
    ll mid=(l+r)>>1;
    build(ls(p),l,mid);
    build(rs(p),mid+1,r);
    push_up(p);
}
void change(ll p,ll l,ll r,ll add){
    lazy_add[p]=lazy_add[p]+add;
    ans[p]=ans[p]+(r-l+1)*add;
}
void push_down(ll p,ll l,ll r){
    ll mid=(l+r)>>1;
    change(ls(p),l,mid,lazy_add[p]);
    change(rs(p),mid+1,r,lazy_add[p]);
    lazy_add[p]=0;
}
void update(ll nl,ll nr,ll l,ll r,ll p,ll k){
    if(nl<=l&&r<=nr){
        ans[p]+=k*(r-l+1);
        lazy_add[p]+=k;
        return;
    }
    push_down(p,l,r);
    ll mid=(l+r)>>1;
    if(nl<=mid) update(nl,nr,l,mid,ls(p),k);
    if(nr>mid) update(nl,nr,mid+1,r,rs(p),k);
    push_up(p);
}
ll query(ll nx,ll ny,ll l,ll r,ll p){
    ll res=0;
    if(nx<=l&&r<=ny) return ans[p];
    push_down(p,l,r);
    int mid=(l+r)>>1;
    if(nx<=mid) res+=query(nx,ny,l,mid,ls(p));
    if(ny>mid) res+=query(nx,ny,mid+1,r,rs(p));
    return res;
}
int main()
{
    ll n,m;
    scanf("%lld%lld",&n,&m);
    for(ll i=1;i<=n;++i){
        scanf("%lld",&a[i]);
    }
    build(1,1,n);
    while(m--){
        ll qs;
        scanf("%lld",&qs);
        if(qs==1){
            ll x,y,k;
            scanf("%lld%lld%lld",&x,&y,&k);
            update(x,y,1,n,1,k);
        }else{
            ll x,y;
            scanf("%lld%lld",&x,&y);
            printf("%lld\n",query(x,y,1,n,1));
        }
    }
    return 0;
}

线段树不是特别了解,希望能借此加深理解。

2022/7/6 20:37
加载中...