线段树区间合并模板题
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=100000+100;
/*
lm:从 l 位置开始的最大的有效子区间的权值和
rm:以 r 位置结束的最大的有效子区间的权值和
m: 区间[l,r]的最大的有效子区间的权值和
sum:区间[l,r]如果是有效区间,则sum是区间[l,r]的权值和,否则是负无穷大
*/
struct Tree{
int l,r;
ll lm,rm,m,sum;
}tree[maxn<<2];
ll val[maxn];
Tree merge(Tree lson,Tree rson){
Tree fa;
fa.l=lson.l;fa.r=rson.r;
fa.lm=lson.lm;fa.rm=rson.rm;
fa.m=max(lson.m,rson.m);
fa.sum=(ll)-1e18;
if((val[lson.r]+val[rson.l])%2){
fa.lm=max(fa.lm,lson.sum+rson.lm);
fa.rm=max(fa.rm,lson.rm+rson.sum);
fa.m=max(fa.m,lson.rm+rson.lm);
fa.sum=max(fa.sum,lson.sum+rson.sum);
}
return fa;
}
void build(int root,int l,int r){
if(l==r){
tree[root].l=tree[root].r=l;
tree[root].lm=tree[root].rm=tree[root].m=tree[root].sum=val[l];
return ;
}
int mid=(l+r)>>1;
build(root<<1,l,mid);
build(root<<1|1,mid+1,r);
tree[root]=merge(tree[root<<1],tree[root<<1|1]);
}
void update(int root,int l,int r,int ind,int v){
if(l==r){
tree[root].lm=tree[root].rm=tree[root].m=tree[root].sum=val[l]=v;
return ;
}
int mid=(l+r)>>1;
if(mid>=ind) update(root<<1,l,mid,ind,v);
else update(root<<1|1,mid+1,r,ind,v);
tree[root]=merge(tree[root<<1],tree[root<<1|1]);
}
Tree query(int root,int l,int r,int L,int R){
if(L<=l && R>=r) return tree[root];
int mid=(l+r)>>1;
if(mid>=R) return query(root<<1,l,mid,L,R);
else if(mid<L) return query(root<<1|1,mid+1,r,L,R);
else return merge(query(root<<1,l,mid,L,R),query(root<<1|1,mid+1,r,L,R));
}
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%lld",&val[i]);
build(1,1,n);
while(m--){
int type,a,b;
scanf("%d%d%d",&type,&a,&b);
if(type) update(1,1,n,a,b);
else printf("%lld\n",query(1,1,n,a,b).m);
}
}