您的位置:首页 > 其它

带修改的区间最大子段和

2017-08-12 21:59 330 查看
维护一个带有两个操作的数据结构:

1.询问[L,R]之间的最大子段和

2.单点修改

题解:

正解:线段树/平衡树

线段树做法:

维护三个东西vl,vr,max,sum:

vl,vr分别表示必须包含区间左\右端点的最大子段和,max为该区间的最大子段和,sum为区间和

然后转移三个变量:

Tree[node].max=max(Tree[ls].max,max(Tree[rs].max,Tree[ls].vr+Tree[rs].vl))
Tree[node].sum=Tree[ls].sum+Tree[rs].sum
Tree[node].vl=max(Tree[ls].vl,Tree[ls].sum+Tree[rs].vl)
Tree[node].vr=max(Tree[rs].vr,Tree[rs].sum+Tree[ls].vr)

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#define ls (node<<1)
#define rs (node<<1|1)
using namespace std;
const int N=500005,inf=2e8;
int n,m,a
;
struct Segtree{
int max,vl,vr,sum,fg;
}Tree[N<<3];
void updata(int node){
Tree[node].max=max(Tree[ls].max,max(Tree[rs].max,Tree[ls].vr+Tree[rs].vl));
Tree[node].sum=Tree[ls].sum+Tree[rs].sum;
Tree[node].vl=max(Tree[ls].vl,Tree[ls].sum+Tree[rs].vl);
Tree[node].vr=max(Tree[rs].vr,Tree[rs].sum+Tree[ls].vr);
}
void build(int l,int r,int node){
Tree[node].fg=true;
if(l==r){
Tree[node].sum=a[l];
Tree[node].max=a[l];
Tree[node].vl=a[l];
Tree[node].vr=a[l];
return ;
}
int mid=(l+r)>>1;
build(l,mid,ls);build(mid+1,r,rs);
updata(node);
}
void add(int l,int r,int node,int ps,int to){
if(l>ps || r<ps)return ;
if(l==r){
Tree[node].sum=to;
Tree[node].max=to;
Tree[node].vl=to;
Tree[node].vr=to;
return ;
}
int mid=(l+r)>>1;
add(l,mid,ls,ps,to);add(mid+1,r,rs,ps,to);
updata(node);
}
Segtree query(int l,int r,int node,int sa,int se){
if(sa<=l && r<=se)return Tree[node];
int mid=(l+r)>>1;
if(sa>mid)return query(mid+1,r,rs,sa,se);
if(se<=mid)return query(l,mid,ls,sa,se);
Segtree t,lson,rson;
lson=query(l,mid,ls,sa,se);rson=query(mid+1,r,rs,sa,se);
t.vl=max(lson.vl,lson.sum+rson.vl);t.vr=max(rson.vr,lson.vr+rson.sum);
t.max=max(lson.vr+rson.vl,max(lson.max,rson.max));
return t;
}
void work()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
build(1,n,1);
int fg,x,y;
while(m--){
scanf("%d%d%d",&fg,&x,&y);
if(fg==2)add(1,n,1,x,y);
else printf("%d\n",query(1,n,1,x,y).max);
}
}

int main()
{
work();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐