西安段素线段树的连续取件最大只连续区间最大值问题模板
#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
",max(res.lv,max(res.mv,res.rv)));
}
}
return 0;
}
//ps:因为没有数据测评,所以可能会有一些小bug,但大体框架就是介样的辣