【题意】
所以我取名就是 oo,ee,oe,eo
- 给一个n(n<=1e5)
- 长度的数列有两种操作
- 1:修改一个点
- 2:查询一个区间,查询一个最大子序列,子序列需满足下标奇偶交替,比方说1,4,5,6,或者4,5,6
【分析】
奇偶交替的序列无非四种情况
- 奇开头偶结尾
- 奇开头奇结尾
- 偶开头奇结尾
- 偶开头偶结尾
然后我就可以存这四个东西了,以o
表示 odd, e表示 even所以我取名就是 oo,ee,oe,eo
【AC代码】
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 100005;
int A[maxn];
struct seg_tree{
struct node{
int l,r;
ll oo,oe,eo,ee;
}Tree[maxn<<2];
node Push_Up(node a,node b){
node res;
res.l=a.l,res.r=b.r;
res.oo = max(max(a.oo,b.oo),max(a.oo+b.eo,a.oe+b.oo));
res.oe = max(max(a.oe,b.oe),max(a.oe+b.oe,a.oo+b.ee));
res.eo = max(max(a.eo,b.eo),max(a.ee+b.oo,a.eo+b.eo));
res.ee = max(max(a.ee,b.ee),max(a.eo+b.ee,a.ee+b.oe));
return res;
}
void Build(int l,int r,int rt){
Tree[rt].l=l,Tree[rt].r=r;
Tree[rt].oo=Tree[rt].oe=Tree[rt].eo=Tree[rt].ee=-1e12;
if(l==r) return ;
int m = (Tree[rt].l+Tree[rt].r)>>1;
Build(l,m,rt<<1);
Build(m+1,r,rt<<1|1);
Tree[rt]=Push_Up(Tree[rt<<1],Tree[rt<<1|1]);
}
void update(int pos,int val,int rt){
if(Tree[rt].l==pos&&Tree[rt].r==pos){
if(pos%2) Tree[rt].oo = val;
else Tree[rt].ee = val;
return ;
}
int m =(Tree[rt].l+Tree[rt].r)>>1;
if(m>=pos) update(pos,val,rt<<1);
else if(m<pos) update(pos,val,rt<<1|1);
Tree[rt] = Push_Up(Tree[rt<<1],Tree[rt<<1|1]);
}
node query_ans(int L,int R,int rt){
if(L==Tree[rt].l&&Tree[rt].r==R){
return Tree[rt];
}
int m = (Tree[rt].l+Tree[rt].r)>>1;
if(R<=m) return query_ans(L,R,rt<<1);
else if(m<L) return query_ans(L,R,rt<<1|1);
else
return Push_Up(query_ans(L,m,rt<<1),query_ans(m+1,R,rt<<1|1));
}
}tree;
int main(){
int T,n,q;
while(~scanf("%d",&T))
{
while(T--){
scanf("%d%d",&n,&q);
tree.Build(1,n,1);
for(int i=1; i<=n; i++){
scanf("%d",&A[i]);
tree.update(i,A[i],1);
}
while(q--){
int op,a,b;
scanf("%d%d%d",&op,&a,&b);
if(op==0){
auto temp = tree.query_ans(a,b,1);
ll ans = max(max(temp.oo,temp.ee),max(temp.oe,temp.eo));
printf("%I64d\n",ans);
}else{
tree.update(a,b,1);
}
}
}
}
return 0;
}