zoukankan      html  css  js  c++  java
  • 支持单点修改,维护最大子段和的线段树 补发一波

    原题luogu

    其实难就难在如何合并区间信息(但是我记得有学长讲过)

    l(tr)表示包含左端点的最大子段和,r(tr)表示包含右端点的最大子段和,mx(tr)表示该区间的最大子段和,sum(tr)表示该区间的总和

    ls表示左儿子,rs表示右儿子

    inline void upd(int tr) {
        l(tr)=max(l(ls),sum(ls)+l(rs));
        mx(tr)=max(max(mx(ls),mx(rs)),r(ls)+l(rs));
        r(tr)=max(r(rs),sum(rs)+r(ls));
        sum(tr)=sum(ls)+sum(rs);
    }

    代码:

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define ll long long
    #define R register ll
    #define ls (tr<<1)
    #define rs (tr<<1|1)
    using namespace std;
    struct node{
        ll mxl,mx,mxr,sum;
        #define l(i) t[i].mxl
        #define mx(i) t[i].mx
        #define r(i) t[i].mxr
        #define sum(i) t[i].sum
    }t[2000010];
    int n,m;
    inline ll g() {
        R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix;
        do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
    }
    inline void upd(int tr) {
        l(tr)=max(l(ls),sum(ls)+l(rs));
        mx(tr)=max(max(mx(ls),mx(rs)),r(ls)+l(rs));
        r(tr)=max(r(rs),sum(rs)+r(ls));
        sum(tr)=sum(ls)+sum(rs);
    }
    inline void build(int tr,ll l,ll r) {
        if(l==r) {l(tr)=mx(tr)=r(tr)=sum(tr)=g(); return ;}
        R md=(l+r)>>1;
        build(ls,l,md),build(rs,md+1,r);
        upd(tr);
    }
    inline void inc(int tr,ll l,ll r,ll pos,ll d) {
        if(l==r) {mx(tr)=l(tr)=r(tr)=sum(tr)=d; return ;}
        R md=(l+r)>>1;
        if(pos>md) inc(rs,md+1,r,pos,d);
        else inc(ls,l,md,pos,d);
        upd(tr);
    }
    inline node query(int tr,ll l,ll r,ll LL,ll RR) {
        if(l==LL&&r==RR) return t[tr];
        R md=(l+r)>>1;
        if(LL>md) return query(rs,md+1,r,LL,RR);
        else if(RR<md+1) return query(ls,l,md,LL,RR);
        register node x=query(ls,l,md,LL,md),y=query(rs,md+1,r,md+1,RR),ret;
        ret.mxl=max(x.mxl,x.sum+y.mxl); ret.mxr=max(y.mxr,x.mxr+y.sum);
        ret.mx=max(max(x.mx,y.mx),x.mxr+y.mxl); ret.sum=x.sum+y.sum;
        return ret;
    }
    signed main() {
        n=g(),m=g();
        memset(t,0xcf,sizeof(t));
        build(1,1,n);
        for(R i=1;i<=m;++i) {
            R k=g(),l=g(),r=g(); 
            if(k&1) {
                if(r<l) swap(l,r);
                printf("%lld
    ",query(1,1,n,l,r).mx);
            } else inc(1,1,n,l,r);
        }
    }

    2019.04.09

  • 相关阅读:
    CentOS7 安装MongoDB 3.0服务
    PXE批量部署linux操作系统
    centos的软件安装方法rpm和yum
    第二章:Posix IPC
    第一章:简介
    Unix网络编程--卷二:进程间通信
    Unix网络编程--卷二:FAQ
    linux下samba环境搭建
    Linux下缓冲区溢出攻击的原理及对策(转载)
    lsof
  • 原文地址:https://www.cnblogs.com/Jackpei/p/10680710.html
Copyright © 2011-2022 走看看