• spoj gss1 gss3


    传送门 gss1 gss3

    spoj gss系列=最大字段和套餐

    gss1就是gss3的无单点修改版

    有区间查询和单点修改,考虑用线段树维护

    我们要维护区间权值和(s),区间最大前缀和(xl)和最大后缀和(xr),以及最大子段和(x)

    在pushup的时候,这样维护 代码里有

    [a[o].s=a[lc].s+a[rc].s$$$$a[o].xl=max(a[lc].xl,a[lc].s+a[rc].xl)$$$$a[o].xr=max(a[rc].xr,a[lc].xr+a[rc].s)$$$$a[o].x=max(max(a[lc].x,a[rc].x),a[lc].xr+a[rc].xl) ]

    其实是懒得写文字

    // luogu-judger-enable-o2
    #include<bits/stdc++.h>
    #define LL long long
    #define il inline
    #define re register
    #define db double
    #define lc (o<<1)
    #define rc ((o<<1)|1)
    #define mid ((l+r)>>1)
    #define max(a,b) ((a)>(b)?(a):(b))
    
    using namespace std;
    const int N=50000+10,inf=999999999;
    il LL rd()
    {
        re LL x=0,w=1;re char ch=0;
        while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
        return x*w;
    }
    struct sgmt
    {
      LL s,xl,xr,x;
    }a[N<<2];
    il void psup(int o)
    {
      a[o].s=a[lc].s+a[rc].s;
      a[o].xl=max(a[lc].xl,a[lc].s+a[rc].xl);
      a[o].xr=max(a[rc].xr,a[lc].xr+a[rc].s);
      a[o].x=max(max(a[lc].x,a[rc].x),a[lc].xr+a[rc].xl);
    }
    il void bui(int o,int l,int r)
    {
      if(l==r) {a[o].s=a[o].xl=a[o].xr=a[o].x=rd();return;}
      bui(lc,l,mid),bui(rc,mid+1,r);
      psup(o);
    }
    il void modi(int o,int l,int r,int x,int y)
    {
      if(l==r) {a[o].s=a[o].xl=a[o].xr=a[o].x=y;return;}
      if(x<=mid) modi(lc,l,mid,x,y);
      else modi(rc,mid+1,r,x,y);
      psup(o);
    }
    il sgmt quer(int o,int l,int r,int ll,int rr)
    {
      if(ll<=l&&r<=rr) return a[o];
      if(rr<=mid) return quer(lc,l,mid,ll,rr);
      else if(ll>mid) return quer(rc,mid+1,r,ll,rr);
      else
        {
          sgmt an,aa,bb;
          aa=quer(lc,l,mid,ll,mid),bb=quer(rc,mid+1,r,mid+1,rr);
          an.s=aa.s+bb.s;
          an.xl=max(aa.xl,aa.s+bb.xl);
          an.xr=max(bb.xr,aa.xr+bb.s);
          an.x=max(max(aa.x,bb.x),aa.xr+bb.xl);
          return an;
        }
    }
    int n,m;
    
    int main()
    {
      n=rd();
      bui(1,1,n);
      m=rd();
      while(m--)
        {
          int op=rd(),x=rd(),y=rd();
          if(op==0) modi(1,1,n,x,y);
          else printf("%lld
    ",quer(1,1,n,x,y).x);
        }
      return 0;
    }
    
    
    
  • 相关阅读:
    每天一道Rust-LeetCode(2019-06-11)
    每天一道Rust-LeetCode(2019-06-10)
    每天一道Rust-LeetCode(2019-06-08)
    每天一道Rust-LeetCode(2019-06-07)
    每天一道Rust-LeetCode(2019-06-06)
    每天一道Rust-LeetCode(2019-06-05)
    每天一道Rust-LeetCode(2019-06-04)
    linux 基本命令
    使用 DrMemory 详细教程
    C++ 虚函数表解析
  • 原文地址:https://www.cnblogs.com/smyjr/p/9608339.html
Copyright © 2020-2023  润新知