ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

P4513 小白逛公园

2022-08-30 14:01:58  阅读:135  来源: 互联网

标签:int nd sum rmax lmax 小白 ans P4513 逛公园


求动态区间最大子段和,并支持单点修改。 \(n\leq 5\times 10^5,m\leq10^5\)。


用线段树处理。对于每一个节点维护以下变量: \(ans\) 表示区间内最大子段和, \(sum\) 表示区间和, \(lmax\) 表示最大前缀和, \(rmax\) 表示最大后缀和,那么对于上传信息时进行以下操作:

\[sum[p]=sum[lson]+sum[rson] \]

\[lmax[p]=max(lmax[lson],sum[lson]+lmax[rson]) \]

\[rmax[p]=max(rmax[rson],sum[rson]+rmax[lson]) \]

\[ans[p]=max(ans[lson],ans[rson],lmax[rson]+rmax[lson]) \]

在询问时也做上述的合并操作即可。

#include<bits/stdc++.h>
using namespace std;

struct node{
	int ans,a;
	int lmax,rmax,sum;
	int l,r;
};



struct ST{
	node nd[2000005];
	inline int ls(int p){
		return p<<1;
	}
	inline int rs(int p){
		return p<<1|1;
	}
	inline void push_up(int p){
		nd[p].sum=nd[ls(p)].sum+nd[rs(p)].sum;
		nd[p].lmax=max(nd[ls(p)].lmax,nd[ls(p)].sum+nd[rs(p)].lmax);
		nd[p].rmax=max(nd[rs(p)].rmax,nd[rs(p)].sum+nd[ls(p)].rmax);
		nd[p].ans=max(nd[ls(p)].ans,nd[rs(p)].ans);
		nd[p].ans=max(nd[p].ans,nd[ls(p)].rmax+nd[rs(p)].lmax);
		return;
	}
	void build(int l,int r,int p){
		nd[p].l=l;
		nd[p].r=r;
		if(l==r){
			nd[p].ans=nd[l].a;
			nd[p].lmax=nd[l].a;
			nd[p].rmax=nd[l].a;
			nd[p].sum=nd[l].a;
			return;
		}
		int mid=(l+r)>>1;
		build(l,mid,ls(p));
		build(mid+1,r,rs(p));
		push_up(p);
		return;
	}
	void updata(int p,int lr,int k){
		if(nd[p].l==nd[p].r && nd[p].l==lr){
			nd[p].ans=k;
			nd[p].lmax=k;
			nd[p].rmax=k;
			nd[p].sum=k;
			return;
		}
		int mid=(nd[p].l+nd[p].r)>>1;
		if(mid>=lr)
			updata(ls(p),lr,k);
		if(mid<lr)
			updata(rs(p),lr,k);
		push_up(p);
		return;
	}
	node query(int p,int ql,int qr){
		int l=nd[p].l;
		int r=nd[p].r;
		if(ql<=l && r<=qr){
			return nd[p];
		}
		node ret,gl,gr;
		int mid=(l+r)>>1;
		if(ql<=mid)
			gl=query(ls(p),ql,qr);
		else if(qr>mid)
			return query(rs(p),ql,qr);
		if(qr>mid)
			gr=query(rs(p),ql,qr);
		else
			return gl;
		ret.sum=gl.sum+gr.sum;
		ret.lmax=max(gl.lmax,gl.sum+gr.lmax);
		ret.rmax=max(gr.rmax,gr.sum+gl.rmax);
		ret.ans=max(gl.ans,gr.ans);
		ret.ans=max(ret.ans,gl.rmax+gr.lmax);
		return ret;
	}
}S;

int n,m;

int main(){
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n;++i)
		scanf("%d",&S.nd[i].a);
	S.build(1,n,1);
	while(m){
		m--;
		int k,a,b;
		scanf("%d %d %d",&k,&a,&b);
		switch(k){
			case 1:{
				if(a>b)
					swap(a,b);
				printf("%d\n",S.query(1,a,b).ans);
				break;
			}
			case 2:{
				S.updata(1,a,b);
				break;
			}
		}
	}
	return 0;
}

标签:int,nd,sum,rmax,lmax,小白,ans,P4513,逛公园
来源: https://www.cnblogs.com/zhouzizhe/p/16639058.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有