求区间奇偶交错最大子序列
线段树模板题
单点更新,区间查询
就是区间合并的时候麻烦一点点,但是也不难
代码如下
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define LL long long
const long long INFF = 0x3f3f3f3f3f3f3f3fll;
struct Info{
LL v[2][2];
void maintain(LL x){
v[0][0]=v[0][1]=v[1][0]=v[1][1]=x;
}
Info(){
maintain(-INFF);
}
LL value(){
LL a=max(v[0][0],v[0][1]);
LL b=max(v[1][0],v[1][1]);
return max(a,b);
}
};
Info operator + (const Info & a,const Info & b){
Info ret;
for(int i=0;i<=1;i++)
for(int j=0;j<=1;j++){
LL & V=ret.v[i][j];
V=max(a.v[i][j],b.v[i][j]);
V=max(V,a.v[i][0]+b.v[1][j]);
V=max(V,a.v[i][1]+b.v[0][j]);
}
return ret;
}
const int maxn = 112345;
Info val[maxn*4];
#define Now int o,int l,int r
#define Mid int m = l + (r - l)/2
#define lson o<<1,l,m
#define rson o<<1|1,m+1,r
#define root 1,1,n
void update(Now,int p,LL v){
if(l==r){
val[o].maintain(-INFF);
val[o].v[l%2][l%2]=v;
return;
}
Mid;
if(p<=m)
update(lson,p,v);
else
update(rson,p,v);
val[o]=val[o<<1]+val[o<<1|1];
}
Info query(Now,int ql,int qr){
if(ql<=l && r<=qr){
return val[o];
}
Mid;
Info ret;
if(ql<=m)
ret = ret + query(lson,ql,qr);
if(m+1<=qr)
ret = ret + query(rson,ql,qr);
return ret;
}
int main(){
int T;
int n,m;
scanf("%d",&T);
while(T-- && ~scanf("%d %d",&n,&m)){
LL x;
for(int i=1;i<=n;i++){
scanf("%lld",&x);
update(root,i,x);
}
int l,r;
int p,ord;
while(m--){
scanf("%d",&ord);
if(ord==0){
scanf("%d %d",&l,&r);
Info ans = query(root,l,r);
printf("%lld\n",ans.value());
}
else{
scanf("%d %lld",&p,&x);
update(root,p,x);
}
}
}
return 0;
}