题意:给你n(n<=10^5)个数ai(-10^9<=ai<=10^9)。要求从这里面取出它的序列,这些序列满足下标奇偶相间,求某段区间的这种序列的最大和值。
分析:最初没读懂题意。。。。 一看数据范围和查询方式,肯定和线段树相关,问题的要求又有点像DP。分析知道,其实就是求线段树的区间合并问题,取出的序列只可能是以奇数开头奇数结尾,奇数开头偶数结尾,偶数开头偶数结尾,偶数开头奇数结尾。用jj,jo,oo,oj表示。当合并的适合考虑这四种情况就是可以了。
jj=max(l.jj ,r.jj, l.jj+r.oj, l.jo+r.jo);其他依次类推
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <string.h>
#include <map>
#include <set>
using namespace std;
#define maxn 200005
#define inff 0x7FFFFFFFFFFFFFFF
typedef __int64 LL;
LL a[maxn];
int n,m;
LL max(LL x,LL y)
{
return x>y?x:y;
}
LL max(LL x,LL y,LL z,LL w)
{
return max(max(x,y),max(z,w));
}
struct node
{
int l,r;
LL oo,jj,jo,oj;
}tr[maxn<<2];
inline LL add(LL x,LL y)
{
if(x==-inff||y==-inff)return -inff;
else return x+y;
}
void pushup(int id)
{
tr[id].jj=max(add(tr[id*2].jo,tr[id*2+1].jj),add(tr[id*2].jj,tr[id*2+1].oj),tr[id*2].jj,tr[id*2+1].jj);
tr[id].oo=max(add(tr[id*2].oj,tr[id*2+1].oo),add(tr[id*2].oo,tr[id*2+1].jo),tr[id*2].oo,tr[id*2+1].oo);
tr[id].jo=max(add(tr[id*2].jj,tr[id*2+1].oo),add(tr[id*2].jo,tr[id*2+1].jo),tr[id*2].jo,tr[id*2+1].jo);
tr[id].oj=max(add(tr[id*2].oo,tr[id*2+1].jj),add(tr[id*2].oj,tr[id*2+1].oj),tr[id*2].oj,tr[id*2+1].oj);
}
void build(int id,int l,int r)
{
tr[id].l=l;
tr[id].r=r;
tr[id].jj=tr[id].oo=-inff;
tr[id].oj=tr[id].jo=-inff;
if(l==r)
{
if(l%2!=0)
{
tr[id].jj=a[l];
tr[id].oo=tr[id].jo=tr[id].oj=-inff;
}
else
{
tr[id].oo=a[l];
tr[id].jj=tr[id].jo=tr[id].oj=-inff;
}
}
else
{
int mid=(l+r)/2;
build(id*2,l,mid);
build(id*2+1,mid+1,r);
pushup(id);
}
}
void update(int id,int pos,LL val)
{
if(tr[id].l==tr[id].r)
{
if(tr[id].l%2!=0)
{
tr[id].jj=val;
tr[id].oo=tr[id].jo=tr[id].oj=-inff;
}
else
{
tr[id].oo=val;
tr[id].jj=tr[id].jo=tr[id].oj=-inff;
}
}
else
{
int mid=(tr[id].l+tr[id].r)/2;
if(pos<=mid)update(id*2,pos,val);
else update(id*2+1,pos,val);
pushup(id);
}
}
node query(int id,int l,int r)
{
if(l<=tr[id].l&&tr[id].r<=r)
{
return tr[id];
}
else
{
int mid=(tr[id].l+tr[id].r)/2;
if(r<=mid)return query(id*2,l,r);
else if(l>mid)return query(id*2+1,l,r);
else
{
node a=query(id*2,l,r);
node b=query(id*2+1,l,r);
node c;
c.jj=max(a.jj,b.jj,add(a.jo,b.jj),add(a.jj,b.oj));
c.oo=max(a.oo,b.oo,add(a.oj,b.oo),add(a.oo,b.jo));
c.jo=max(a.jo,b.jo,add(a.jj,b.oo),add(a.jo,b.jo));
c.oj=max(a.oj,b.oj,add(a.oo,b.jj),add(a.oj,b.oj));
return c;
}
}
}
int main()
{
int t,i;
//cout<<inff<<endl;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
{
scanf("%I64d",&a[i]);
}
build(1,1,n);
//cout<<tr[1].jj<<" "<<tr[1].oo<<" "<<tr[1].oj<<endl;
for(i=1;i<=m;i++)
{
int pos;
LL val;
int c,l,r;
scanf("%d",&c);
if(c==1)
{
scanf("%d%I64d",&pos,&val);
update(1,pos,val);
}
else
{
scanf("%d%d",&l,&r);
node ans=query(1,l,r);
printf("%I64d\n",max(ans.jj,ans.jo,ans.oo,ans.oj));
}
}
}
return 0;
}