最大子段和---线段树(板)

学习粗:https://www.cnblogs.com/qq2210446939/p/12572525.html

模板:

#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=;
typedef long long ll;

ll A[maxn];
struct node{
    ll ls,rs,ms,s;
}a[maxn<<2];

void pushup(int rt){
    int lson=rt<<1;
    int rson=rt<<1|1;
    a[rt].s=a[lson].s+a[rson].s;
    a[rt].ls=max(a[lson].ls , a[lson].s+a[rson].ls);
    a[rt].rs=max(a[rson].rs , a[rson].s+a[lson].rs);
    a[rt].ms=max(max(a[lson].ms,a[rson].ms),a[lson].rs+a[rson].ls);
}

void build(int l,int r,int rt){
    if(l==r){
        a[rt].ls=a[rt].rs=a[rt].ms=a[rt].s=A[l];
        return;
    }
    int m=l+r>>1;
    build(l,m,rt<<1);
    build(m+1,r,rt<<1|1);
    pushup(rt);
}

void update(int pos,ll val,int l,int r,int rt){
    //pos位置加val 
    if(l==r){
        ll tmp=a[rt].ms+val;
        a[rt].ls=a[rt].rs=a[rt].s=a[rt].ms=tmp;
        return;
    }
    int m=l+r>>1;
    if(pos<=m)
        update(pos,val,l,m,rt<<1);
    else
        update(pos,val,m+1,r,rt<<1|1);
    pushup(rt);
}

node query(int L,int R,int l,int r,int rt){
    //返回代表查询区间信息的节点 
    if(L<=l&&r<=R){
        return a[rt];
    }
    int m=l+r>>1;
    node f1,f2,ans;
    if(R<=m)
        ans=query(L,R,l,m,rt<<1);
    if(L>m)
        ans=query(L,R,m+1,r,rt<<1|1);
    if(L<=m&&R>m){
        f1=query(L,R,l,m,rt<<1);
        f2=query(L,R,m+1,r,rt<<1|1);
        ans.s=f1.s+f2.s;
        ans.ls=max(f1.ls,f1.s+f2.ls);
        ans.rs=max(f2.rs,f2.s+f1.rs);
        ans.ms=max(max(f1.ms,f2.ms),f1.rs+f2.ls);
    }
    return ans;
}

int main()
{
    
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/starve/p/12614895.html