解析:關鍵是處理奇偶的問題。
正如官方題解所說,本題的子序列實際上可以根據起始數值下標的奇偶性分爲四類。
對於每一類,如果你熟悉線段樹,那麼可以看出這個問題是可以進行區間合併的。
即如果知道一個區間[L, R]兩個子區間 [L,mid], [mid+1,R]的信息,我們可以推出[L,R][L,R]的信息。
維護四個值,表示起點終點的下標的奇偶性。
[code]:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
using namespace std;
typedef long long LL;
const int maxn = 1e5+5;
const int INF = 0x3f3f3f3f;
struct Node{
LL v0,v1,v2,v3;
Node(){}
Node(LL v0,LL v1,LL v2,LL v3):v0(v0),v1(v1),v2(v2),v3(v3){}
void init(LL v0,LL v1,LL v2,LL v3){
this->v0 = v0;this->v1 = v1;
this->v2 = v2;this->v3 = v3;
}
LL answer(){
return max(max(v0,v1),max(v2,v3));
}
};
void build(int,int,int) __attribute__((optimize("O3")));
void update(int,int,int,int,int) __attribute__((optimize("O3")));
Node query(int,int,int,int,int) __attribute__((optimize("O3")));
inline bool read(int &ret){
char c;int sgn;
if(c = getchar(),c==EOF) return 0;
while(c != '-'&&(c<'0'||c>'9')) c=getchar();
sgn = (c=='-')?-1:1;
ret = (c=='-')?0:(c-'0');
while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
ret*=sgn;
return 1;
}
int n,m,a[maxn];
LL C[4*maxn][4];
void push_up(int rt){
C[rt][0] = max(C[rt<<1][0],max(C[rt<<1|1][0],max(C[rt<<1][0]+C[rt<<1|1][2],C[rt<<1][1]+C[rt<<1|1][0])));
C[rt][1] = max(C[rt<<1][1],max(C[rt<<1|1][1],max(C[rt<<1][1]+C[rt<<1|1][1],C[rt<<1][0]+C[rt<<1|1][3])));
C[rt][2] = max(C[rt<<1][2],max(C[rt<<1|1][2],max(C[rt<<1][2]+C[rt<<1|1][2],C[rt<<1][3]+C[rt<<1|1][0])));
C[rt][3] = max(C[rt<<1][3],max(C[rt<<1|1][3],max(C[rt<<1][2]+C[rt<<1|1][3],C[rt<<1][3]+C[rt<<1|1][1])));
}
void build(int l,int r,int rt){
if(l == r){
if(l&1) C[rt][0] = a[l],C[rt][3] = -INF;
else C[rt][0] = -INF,C[rt][3] = a[l];
C[rt][1] = C[rt][2] = -INF;
return;
}
int mid = (l+r)>>1;
build(lson);build(rson);
push_up(rt);
}
void update(int k,int x,int l,int r,int rt){
if(l == r){
if(k&1) C[rt][0] = x;
else C[rt][3] = x;
return;
}
int mid = (l+r)>>1;
if(k <= mid) update(k,x,lson);
else update(k,x,rson);
push_up(rt);
}
Node query(int a,int b,int l,int r,int rt){
if(a<=l&&r<=b) return Node(C[rt][0],C[rt][1],C[rt][2],C[rt][3]);
int mid = (l+r)>>1;
if(b<=mid) return query(a,b,lson);
else if(a > mid) return query(a,b,rson);
else{
Node ls,rs,s;
ls = query(a,b,lson);rs = query(a,b,rson);
s.v0 = max(max(ls.v0,rs.v0),max(ls.v0+rs.v2,ls.v1+rs.v0));
s.v1 = max(max(ls.v1,rs.v1),max(ls.v1+rs.v1,ls.v0+rs.v3));
s.v2 = max(max(ls.v2,rs.v2),max(ls.v2+rs.v2,ls.v3+rs.v0));
s.v3 = max(max(ls.v3,rs.v3),max(ls.v2+rs.v3,ls.v3+rs.v1));
return s;
}
}
int main(){
int i,j,cas,op,l,r;
scanf("%d",&cas);
while(cas--){
read(n);read(m);
for(i = 1;i <= n;i++) read(a[i]);
build(1,n,1);
while(m--){
read(op);read(l);read(r);
if(op==0){
printf("%I64d\n",query(l,r,1,n,1).answer());
}else{
update(l,r,1,n,1);
}
}
}
return 0;
}