西安段素的取件最大只问题模板

西安段素线段树的连续取件最大只连续区间最大值问题模板

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
struct node
{
	int sum;//总和
	int lv;//左起最大值
	int rv;//右起最大值
	int mv;//中间的最大值
};
node t[100000];
node null;
int base[100000];
void push_up(int root,int l,int m,int r)
{
	int _mv=0;
	t[root].sum=t[root<<1].sum+t[root<<1|1].sum;//合并总和,至于为什么要记录介个值,下面会用到
	t[root].lv=t[root].rv=t[root].mv=0;//归零
	t[root].lv=max(t[root<<1].lv,t[root<<1].sum+t[root<<1|1].lv);//从左起的最大值要么是左区间的左起最大,或者是左区间的全部加上右区间的左起最大值,这里就用到了sum
	t[root].rv=max(t[root<<1|1].rv,t[root<<1|1].sum+t[root<<1].rv);
	t[root].mv=max(t[root<<1].mv,max(t[root<<1|1].mv,t[root<<1].rv+t[root<<1|1].lv));//中间的最大值有三种情况,1.左区间的中间最大,2.右区间的中间最大,3.将左右区间拼起来的中间前左右拓展的最大值。
	return ;
}
void build(int root,int l,int r)
{
	if(l==r)
	{
		t[root].lv=t[root].mv=t[root].rv=t[root].sum=base[l];
		return ;
	}
	int mid=(l+r)>>1;
	build(root<<1,l,mid);
	build(root<<1|1,mid+1,r);
	push_up(root,l,mid,r);
}
void change(int root,int l,int r,int al,int ar,int k)//单点修改,只不过是强迫症写成立类似区间修改额样子
{
	if(l>ar||r<al)
		return ;
	if(l>=al&&r<=ar)
	{
		t[root].sum=t[root].lv=t[root].rv=t[root].mv=k;
		return ;
	}
	int mid=(l+r)>>1;
	change(root<<1,l,mid,al,ar,k);
	change(root<<1|1,mid+1,r,al,ar,k);
	push_up(root,l,mid,r);
	return ;
}
node check(int root,int l,int r,int al,int ar)
{
	if(l>ar||r<al)
		return null;//自定义的空
	if(l>=al&&r<=ar)
		return t[root];
	int mid=(l+r)>>1;
	node t1=check(root<<1,l,mid,al,ar);//对于询问的合并跟push_up是一样的。
	node t2=check(root<<1|1,mid+1,r,al,ar);
	node res;
	res.sum=t1.sum+t2.sum;
	res.lv=max(t1.lv,t1.sum+t2.lv);
	res.rv=max(t2.rv,t2.sum+t1.rv);
	res.mv=max(t1.rv+t2.lv,max(t1.mv,t2.mv));
	return res;
}
void init()
{
	null.sum=-0x7fffffff;
	null.mv=-0x7fffffff;
	null.lv=-0x7fffffff;
	null.rv=-0x7fffffff;//不影响答案的无限小
	return ;
}
int main()
{
	init();
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		scanf("%d",&base[i]);
	build(1,1,n);
	int a,b,c;
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&a,&b,&c);
		if(a==1)
			change(1,1,n,b,b,c);
		else
		{
			node res=check(1,1,n,b,c);			
			printf("%d\n",max(res.lv,max(res.mv,res.rv)));
		}
	}
	return 0;
}
//ps:因为没有数据测评,所以可能会有一些小bug,但大体框架就是介样的辣
posted @ 2018-06-03 19:28  Lance1ot  阅读(127)  评论(0编辑  收藏  举报