题意:对数字序列有两个操作,1是将值修改,而0是询问a到b的最大值,最大值定义为所选的相邻的数的下标一个为偶数一个为奇数
思路:肯定是线段树的题目,因为有这样的限制条件那么会用到线段树的区间合并,而这道题我们可以找最大值的情况很多,1可以是奇数开头奇数结束的,2可以是奇数开头偶数结束的,3可以是偶数开头奇数结束的,4可以是偶数开头偶数结束的,所以我们最后的最大值也要在这四个里面选,那么我们就要维护四个最大值了,而区间更新的操作就是模版用就好了,唯一要注意的就是在返回的时候我们不能直接返回四个中最大值,因为最下面的时候我们还可能有一个合并的操作
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f;
const int maxn=100010;
ll max1[maxn*4],max2[maxn*4],max3[maxn*4],max4[maxn*4],A[maxn];//jj jo oj oo
struct pos{
ll aa,ab,ba,bb;
};
void pushup(int node){
max1[node]=max(max1[node<<1],max(max1[node<<1|1],max(max1[node<<1]+max3[node<<1|1],max2[node<<1]+max1[node<<1|1])));
max2[node]=max(max2[node<<1],max(max2[node<<1|1],max(max2[node<<1]+max2[node<<1|1],max1[node<<1]+max4[node<<1|1])));
max3[node]=max(max3[node<<1],max(max3[node<<1|1],max(max4[node<<1]+max1[node<<1|1],max3[node<<1]+max3[node<<1|1])));
max4[node]=max(max4[node<<1],max(max4[node<<1|1],max(max3[node<<1]+max4[node<<1|1],max4[node<<1]+max2[node<<1|1])));
}
void buildtree(int le,int ri,int node){
max1[node]=max2[node]=max3[node]=max4[node]=-INF;
if(le==ri){
if(le%2==0) max4[node]=A[le];
else max1[node]=A[le];
return ;
}
int t=(le+ri)>>1;
buildtree(le,t,node<<1);
buildtree(t+1,ri,node<<1|1);
pushup(node);
}
void update(int pos,int val,int le,int ri,int node){
if(le==ri){
if(pos%2==0) max4[node]=(ll)val;
else max1[node]=(ll)val;
return ;
}
int t=(le+ri)>>1;
if(pos<=t) update(pos,val,le,t,node<<1);
else update(pos,val,t+1,ri,node<<1|1);
pushup(node);
}
pos query(int l,int r,int le,int ri,int node){
if(l<=le&&ri<=r){
pos s;
s.aa=max1[node];s.ab=max2[node],s.ba=max3[node],s.bb=max4[node];
return s;
}
int t=(le+ri)>>1;
if(r<=t) return query(l,r,le,t,node<<1);
if(l>t) return query(l,r,t+1,ri,node<<1|1);
pos ans1=query(l,r,le,t,node<<1);
pos ans2=query(l,r,t+1,ri,node<<1|1);
pos ans3;
ans3.aa=max(ans1.aa,max(ans2.aa,max(ans1.aa+ans2.ba,ans1.ab+ans2.aa)));
ans3.ab=max(ans1.ab,max(ans2.ab,max(ans1.ab+ans2.ab,ans1.aa+ans2.bb)));
ans3.ba=max(ans1.ba,max(ans2.ba,max(ans1.bb+ans2.aa,ans1.ba+ans2.ba)));
ans3.bb=max(ans1.bb,max(ans2.bb,max(ans1.ba+ans2.bb,ans1.bb+ans2.ab)));
return ans3;
}
int main(){
int T,n,m,a,b,c;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%I64d",&A[i]);
buildtree(1,n,1);
while(m--){
scanf("%d%d%d",&a,&b,&c);
if(a==1) update(b,c,1,n,1);
else{
pos ans=query(b,c,1,n,1);
printf("%I64d\n",max(ans.aa,max(ans.ab,max(ans.ba,ans.bb))));
}
}
}
return 0;
}