链接:https://vijos.org/p/1083
这题让维护子区间最大值,查询子区间最大值
于是在父亲节点的子区间最大值可能
1. 完全在左儿子中
2. 完全在右儿子中
3. 左右儿子各一半
于是就有
segtree[i].smax=max(max(segtree[i<<1].smax,segtree[(i<<1)^1].smax),segtree[(i<<1)^1].lmax+segtree[i<<1].rmax);
所以就要维护:1.子区间最大值 2.区间从最左开始最大值 3. 区间从最右开始最大值。
于是就有
segtree[i].lmax=max(segtree[i<<1].lmax,segtree[i<<1].sum+segtree[(i<<1)^1].lmax);
segtree[i].rmax=max(segtree[(i<<1)^1].rmax,segtree[(i<<1)^1].sum+segtree[i<<1].rmax);
segtree[i].smax=max(max(segtree[i<<1].smax,segtree[(i<<1)^1].smax),segtree[(i<<1)^1].lmax+segtree[i<<1].rmax);
所以还要维护:区间和
于是就有
segtree[i].sum=segtree[i<<1].sum+segtree[(i<<1)^1].sum;
最后注意一下query()的写法
最后上代码
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int m=1,n,qu;
struct o
{
int lmax;
int rmax;
int smax;
int sum;
}segtree[2000000];
o query(int pos,int l,int r,int f,int t)
{
int mid=(l+r)>>1;
if(l>=f&&r<=t)
return segtree[pos];
else if(t<=mid)
return query(pos<<1,l,mid,f,t);
else if(f>mid)
return query((pos<<1)+1,mid+1,r,f,t);
else
{
o w1=query(pos<<1,l,mid,f,t);
o w2=query((pos<<1)+1,mid+1,r,f,t);
int relmax=max(w1.lmax,w1.sum+w2.lmax);
int rermax=max(w2.rmax,w1.rmax+w2.sum);
int resum=w1.sum+w2.sum;
int resmax=max(max(w1.smax,w2.smax),w1.rmax+w2.lmax);
return (o){relmax,rermax,resmax,resum};
}
}
int main()
{
scanf("%d%d",&n,&qu);
while(m<=n)m<<=1;
for(int i=m+1;i<=m+n;i++)
{
scanf("%d",&segtree[i].lmax);
segtree[i].rmax=segtree[i].lmax;
segtree[i].smax=segtree[i].lmax;
segtree[i].sum=segtree[i].lmax;
}
for(int i=m-1;i>=1;i--)
{
segtree[i].lmax=max(segtree[i<<1].lmax,segtree[i<<1].sum+segtree[(i<<1)^1].lmax);
segtree[i].rmax=max(segtree[(i<<1)^1].rmax,segtree[(i<<1)^1].sum+segtree[i<<1].rmax);
segtree[i].sum=segtree[i<<1].sum+segtree[(i<<1)^1].sum;
segtree[i].smax=max(max(segtree[i<<1].smax,segtree[(i<<1)^1].smax),segtree[(i<<1)^1].lmax+segtree[i<<1].rmax);
}
int temp=0;
for(int i=1;i<=qu;i++)
{
int t,x,y;
scanf("%d%d%d",&t,&x,&y);
if(t==2)
{
segtree[x+m].sum=y;
segtree[x+m].lmax=y;
segtree[x+m].rmax=y;
segtree[x+m].smax=y;
for(int i=(x+m)>>1;i;i>>=1)
{
segtree[i].lmax=max(segtree[i<<1].lmax,segtree[i<<1].sum+segtree[(i<<1)^1].lmax);
segtree[i].rmax=max(segtree[(i<<1)^1].rmax,segtree[(i<<1)^1].sum+segtree[i<<1].rmax);
segtree[i].sum=segtree[i<<1].sum+segtree[(i<<1)^1].sum;
segtree[i].smax=max(max(segtree[i<<1].smax,segtree[(i<<1)^1].smax),segtree[(i<<1)^1].lmax+segtree[i<<1].rmax);
}
}else
{
if(temp==1)
printf("\n");
else temp=1;
if(x>y)swap(x,y);
printf("%d",query(1,0,m-1,x,y).smax);
}
}
return 0;
}