题目链接:点击查看
题目大意:给出长度为 n 的数列 a ,接下来进行 m 次操作,每次操作分为两种类型:
- 0 l r:询问区间 [ l , r ] 内的最长子序列之和,要求相邻两个位置的下标奇偶性不同
- 1 pos val:修改 pos 位置的数字为 val
题目分析:需要用到区间合并,因为下标奇偶性不同,所以在合并的时候,一共只有四种情况:奇奇,奇偶,偶奇,偶偶,直接分情况维护最大值就好了
代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
const LL inf=0x3f3f3f3f3f3f3f3f;
const int N=1e5+100;
struct Node
{
int l,r;
LL oo,jj,oj,jo;
}tree[N<<2];
void pushup(int k)
{
Node &a=tree[k<<1],&b=tree[k<<1|1];
tree[k].jj=max(max(a.jj,b.jj),max(a.jj+b.oj,a.jo+b.jj));
tree[k].oo=max(max(a.oo,b.oo),max(a.oo+b.jo,a.oj+b.oo));
tree[k].jo=max(max(a.jo,b.jo),max(a.jj+b.oo,a.jo+b.jo));
tree[k].oj=max(max(a.oj,b.oj),max(a.oo+b.jj,a.oj+b.oj));
}
void init(int k,LL val,int pos)
{
tree[k].oo=tree[k].jj=tree[k].oj=tree[k].jo=-inf;
if(pos&1)
tree[k].jj=val;
else
tree[k].oo=val;
}
void build(int k,int l,int r)
{
tree[k].l=l;
tree[k].r=r;
if(l==r)
{
LL val;
scanf("%lld",&val);
init(k,val,l);
return;
}
int mid=l+r>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
pushup(k);
}
void change(int k,int pos,LL val)
{
if(tree[k].l==tree[k].r)
{
init(k,val,tree[k].l);
return;
}
int mid=tree[k].l+tree[k].r>>1;
if(pos<=mid)
change(k<<1,pos,val);
else
change(k<<1|1,pos,val);
pushup(k);
}
Node query(int k,int l,int r)
{
if(tree[k].l>=l&&tree[k].r<=r)
return tree[k];
int mid=tree[k].l+tree[k].r>>1;
if(r<=mid)
return query(k<<1,l,r);
else if(l>mid)
return query(k<<1|1,l,r);
else
{
Node a=query(k<<1,l,r),b=query(k<<1|1,l,r),ans;
ans.jj=max(max(a.jj,b.jj),max(a.jj+b.oj,a.jo+b.jj));
ans.oo=max(max(a.oo,b.oo),max(a.oo+b.jo,a.oj+b.oo));
ans.jo=max(max(a.jo,b.jo),max(a.jj+b.oo,a.jo+b.jo));
ans.oj=max(max(a.oj,b.oj),max(a.oo+b.jj,a.oj+b.oj));
return ans;
}
}
int main()
{
#ifndef ONLINE_JUDGE
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
#endif
// ios::sync_with_stdio(false);
int w;
cin>>w;
while(w--)
{
int n,m;
scanf("%d%d",&n,&m);
build(1,1,n);
while(m--)
{
int op;
scanf("%d",&op);
if(op==1)
{
int pos;
LL val;
scanf("%d%lld",&pos,&val);
change(1,pos,val);
}
else if(op==0)
{
int l,r;
scanf("%d%d",&l,&r);
Node t=query(1,l,r);
printf("%lld\n",max(max(t.jj,t.oo),max(t.oj,t.jo)));
}
}
}
return 0;
}