你能回答这些问题吗

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\n",query(1,x,y).data);
		}
		else change(1,x,y);
	}
    return 0;
}

posted on 2019-10-11 16:52  PPXppx  阅读(159)  评论(0编辑  收藏  举报