• 你能回答这些问题吗


    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;
    }
    
    
  • 相关阅读:
    poj 1328 Radar Installation (贪心)
    hdu 2037 今年暑假不AC (贪心)
    poj 2965 The Pilots Brothers' refrigerator (dfs)
    poj 1753 Flip Game (dfs)
    hdu 2838 Cow Sorting (树状数组)
    hdu 1058 Humble Numbers (DP)
    hdu 1069 Monkey and Banana (DP)
    hdu 1087 Super Jumping! Jumping! Jumping! (DP)
    必须知道的.NET FrameWork
    使用记事本+CSC编译程序
  • 原文地址:https://www.cnblogs.com/PPXppx/p/11655249.html
Copyright © 2020-2023  润新知