• 你能回答这些问题吗


    AcWing

    题意:两种操作,一是单点修改,二是查询区间最大子段和.

    操作一是常规操作,对于操作二,线段树上我们要维护每个节点(区间)的最大左子段和,最大右子段和,最大子段和,以及区间和四个东西.

    然后更新就是:

    t[p].sum=t[p<<1].sum+t[p<<1|1].sum;
    t[p].lmax=max(t[p<<1].lmax,t[p<<1].sum+t[p<<1|1].lmax);
    t[p].rmax=max(t[p<<1|1].rmax,t[p<<1|1].sum+t[p<<1].rmax);
    t[p].data=max(t[p<<1].data,max(t[p<<1|1].data,t[p<<1].rmax+t[p<<1|1].lmax));
    

    查询的话,一个区间的最大子段和,同更新类似,会有多种来源,可能是左子区间的最大左子段和,右子区间的最大右子段和,左子区间的最大右子段和加上右子区间的最大左子段和.都要考虑到.

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<map>
    #include<set>
    #define ll long long
    using namespace std;
    inline int read(){
        int x=0,o=1;char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
        if(ch=='-')o=-1,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*o;
    }
    const int N=500005;
    int n,m,val[N];
    struct XD_Tree{int l,r,lmax,rmax,sum,data;}t[N<<2];
    inline void build(int p,int l,int r){
    	t[p].l=l;t[p].r=r;
    	if(l==r){
    		t[p].lmax=t[p].rmax=t[p].sum=t[p].data=val[l];
    		return;
    	}
    	int mid=(l+r)>>1;
    	build(p<<1,l,mid);build(p<<1|1,mid+1,r);
    	t[p].sum=t[p<<1].sum+t[p<<1|1].sum;
    	t[p].lmax=max(t[p<<1].lmax,t[p<<1].sum+t[p<<1|1].lmax);
    	t[p].rmax=max(t[p<<1|1].rmax,t[p<<1|1].sum+t[p<<1].rmax);
    	t[p].data=max(t[p<<1].data,max(t[p<<1|1].data,t[p<<1].rmax+t[p<<1|1].lmax));
    }
    inline void change(int p,int pos,int v){
    	if(t[p].l==t[p].r){
    		t[p].lmax=t[p].rmax=t[p].sum=t[p].data=v;
    		return;
    	}
    	int mid=(t[p].l+t[p].r)>>1;
    	if(pos<=mid)change(p<<1,pos,v);
    	else change(p<<1|1,pos,v);
    	t[p].sum=t[p<<1].sum+t[p<<1|1].sum;
    	t[p].lmax=max(t[p<<1].lmax,t[p<<1].sum+t[p<<1|1].lmax);
    	t[p].rmax=max(t[p<<1|1].rmax,t[p<<1|1].sum+t[p<<1].rmax);
    	t[p].data=max(t[p<<1].data,max(t[p<<1|1].data,t[p<<1].rmax+t[p<<1|1].lmax));
    }
    inline XD_Tree query(int p,int ql,int qr){
    	int l=t[p].l,r=t[p].r;
        if(ql<=l&&qr>=r)return t[p];
        int mid=(l+r)>>1;XD_Tree a,b,c;
        a.data=a.sum=a.lmax=a.rmax=-1e9;
        b.data=b.sum=b.lmax=b.rmax=-1e9;
        c.sum=0;
        if(ql<=mid){
            a=query(p<<1,ql,qr);
            c.sum+=a.sum;
        }
        if(qr>mid){
            b=query(p<<1|1,ql,qr);
            c.sum+=b.sum;
        }
        c.data=max(max(a.data,b.data),a.rmax+b.lmax);
        c.lmax=max(a.lmax,b.lmax+a.sum);
        if(ql>mid)c.lmax=max(c.lmax,b.lmax);
        c.rmax=max(b.rmax,b.sum+a.rmax);
        if(qr<=mid)c.rmax=max(c.rmax,a.rmax);
        return c;
    }
    int main(){
    	n=read();m=read();
    	for(int i=1;i<=n;++i)val[i]=read();
    	build(1,1,n);
    	while(m--){
    		int opt=read(),x=read(),y=read();
    		if(opt==1){
    			if(x>y)swap(x,y);
    			printf("%d
    ",query(1,x,y).data);
    		}
    		else change(1,x,y);
    	}
        return 0;
    }
    
    
  • 相关阅读:
    centos7中如何让网卡名不被改变
    设置git使用vim作为编辑器
    vim复制时保留原有格式
    Linux添加自定义命令方法
    从graphite中删除字段信息
    jquery图片上传新思路
    注册代码
    JQ基本和层级选择器-p9-09
    DOM对象和JQ对象相互转换
    DOM对象和JQuery对象
  • 原文地址:https://www.cnblogs.com/PPXppx/p/11655249.html
Copyright © 2020-2023  润新知