zoukankan      html  css  js  c++  java
  • 洛谷 SP1716 GSS3

    题目链接

    话说真的和GSS1有什么区别,除了一个修改操作...

    0x00 思路

    最大子段和是区间内一段连续元素的和,不妨当成一段区间来看,那么对于一段区间([l,r])的最大子段和,有存在三种情况

    定义(mid = (l + r) / 2)

    1. 完全位于([l,mid])

    2. 完全位于([mid+1,r])

    3. 左端点在([l,mid]),右端点在([mid+1,r])

    这样,维护区间最大子段和,我们就要知道以下三个值:

    1. 子区间最大子段和

    2. 左区间的最大后缀和

    3. 右区间的最大前缀和

    对于(1)我们很好理解,那么(2)(3)呢?

    当左右端点分居在两个区间内时,我们发现它们之间没有关系,就是由一段前缀,一段后缀连接而成,分开讨论即可

    接下来,为了维护最大前/后缀和,我们又要知道以下六个值

    1. 左区间的区间和/最大前缀和/最大后缀和

    2. 右区间的区间和/最大前缀和/最大后缀和

    最大前缀和 = max(左区间最大前缀和 , 左区间区间和 + 右区间最大前缀和)

    最大后缀和 = max(右区间最大后缀和 , 右区间区间和 + 左区间最大后缀和)

    这下解决了,可以上线段树维护了

    你问我区间和怎么维护?我只能呵呵

    0x01 Code

    #include<bits/stdc++.h>
    using namespace std;
    #define mid ((l+r)>>1)
    #define ls (nod<<1)
    #define rs (nod<<1|1)
    #define lson ls,l,mid
    #define rson rs,mid+1,r
    
    int read(){
    	int x=0; char c=getchar(); int flag=1;
    	while(!isdigit(c)) { if(c=='-') flag=-1; c=getchar(); }
    	while(isdigit(c)) { x=((x+(x<<2))<<1)+(c^48); c=getchar(); }
    	return x*flag;
    }
    
    const int N=5e5+50;
    
    int n,q;
    
    struct Node{
        int l,r;
        int lv,rv,v,sum;
        
    }t[N<<2];
    
    Node Union(Node a,Node b){
        Node c;
        c.l=a.l; c.r=b.r;
        c.lv=max(a.lv,a.sum+b.lv);
        c.rv=max(b.rv,b.sum+a.rv);
        c.sum=a.sum+b.sum;
        c.v=max(max(a.v,b.v),a.rv+b.lv);
        return c;
    }
    
    void pushup(int nod){
        if(t[nod].l==t[nod].r) return ;
        t[nod]=Union(t[ls],t[rs]);
    }
    
    void build(int nod,int l,int r){
        t[nod].l=l; t[nod].r=r;
        if(l==r){
    	    t[nod].sum=t[nod].lv=t[nod].rv=t[nod].v=read();
    	    return ;
    	}
    	build(lson); build(rson);
    	pushup(nod);
    }
    
    void update(int nod,int l,int r,int ps,int val){
        if(l==r){
    	    t[nod].lv=t[nod].rv=t[nod].v=t[nod].sum=val;
    	    return ;
    	}
    	if(ps<=mid) update(lson,ps,val);
    	else update(rson,ps,val);
    	pushup(nod);
    }
    
    Node query(int nod,int l,int r,int ll,int rr){
        if(ll==l&&r==rr){
    	    return t[nod];
    	}
    	if(rr<=mid) return query(lson,ll,rr);
    	else if(ll>mid) return query(rson,ll,rr);
    	else return Union(query(lson,ll,mid),query(rson,mid+1,rr));
    }
    
    signed main(){
        n=read();
        build(1,1,n);
        q=read();
        while(q--){
    	    int opt=read(),x=read(),y=read();
    	    if(opt==0){
    		    update(1,1,n,x,y);
    		}else{
    		    printf("%d
    ",query(1,1,n,x,y).v);
    		}
    	}
        return 0;
    }
    
    
  • 相关阅读:
    基于Grafana+SimpleJson的灵活报表解决方案
    Scala安装时的坑
    Windows批量添加防火墙例外端口
    VMware与Hyper-V
    InfluxDB:cannot use field in group by clause
    .Net版InfluxDB客户端使用时的一些坑
    KafkaManager中Group下不显示对应Topic的解决方案
    Linux下查看Go语言软件运行情况
    Flink升级到1.4版本遇到的坑
    spring cloud(一)带你进入分布式
  • 原文地址:https://www.cnblogs.com/zzhzzh123/p/12240645.html
Copyright © 2011-2022 走看看