zoukankan      html  css  js  c++  java
  • 线段树—最大字段和

    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int maxn=5e5+10;
    typedef long long ll;
    int n,m;
    struct node{
        ll ls,rs,ms,s;
    }a[maxn<<2];
    
    int A[maxn];
    
    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,int val,int l,int r,int rt){
        if(l==r){
            a[rt].ls=a[rt].rs=a[rt].ms=a[rt].s=val;
            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){//查询 L 到 R 区间内的最大字段和
        if(L<=l&&r<=R){
            return a[rt];
        }
        int m=l+r>>1;
        node ans,f1,f2;
        ans.s=0;
        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;
    }
    
    void check(){
        for(int i=1;i<=9;i++)
            cout<<a[i].s<<" ";
        cout<<endl;
    }
    
    int main()
    {
        cin>>n>>m;
        for(int i=1;i<=n;i++)
            cin>>A[i];
        build(1,n,1);
        //check();
        int A,B,C;
        for(int i=1;i<=m;i++){
            cin>>A>>B>>C;
            if(A==1){
                if (B>C) swap(B,C);
                cout<<query(B,C,1,n,1).ms<<'
    ';
            }
            else
                update(B,C,1,n,1);
        }
        return 0;
    }
  • 相关阅读:
    POJ 2195 Going Home (费用流)
    POJ 1087 A Plug for UNIX (网络流,最大流)
    凸包的直径——旋转卡壳
    凸包--Graham扫描法
    POJ 3167 Layout(差分约束)
    POJ 2187 Beauty Contest(凸包,旋转卡壳)
    HDU 1392 Surround the Trees(凸包)
    HDU 3416 Marriage Match IV(最短路,网络流)
    【USACO4.2】草地排水Drainage Ditches(最大流)
    【模板】网络最大流
  • 原文地址:https://www.cnblogs.com/qq2210446939/p/12133692.html
Copyright © 2011-2022 走看看