题意:
对线段树区间有两种操作:
1 改变某一位置的值
0 求所给l r区间的最大和子序列,子序列满足相邻位置的点在原串中的位置的奇偶序不同。
思路:
#include<iostream>
#include<stdio.h>
#include<math.h>
#include <string>
#include<string.h>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<stdlib.h>
using namespace std;
#define eps 1e-13
#define inf 0x3f3f3f3f
#define rd(x) scanf("%d",&x)
#define rd2(x,y) scanf("%d%d",&x,&y)
#define ll long long int
#define mod 998244353
#define maxn 100005
#define maxm 100005
int f[maxn],t,n,m,a,b,q;
struct Node
{
ll s00,s01,s11,s10;
}nd[maxn*4];
ll mx(ll a,ll b){
return a>b?a:b;
}
void setnd(int rt){
nd[rt].s00=mx(nd[rt*2].s00+nd[rt*2+1].s10,nd[rt*2].s01+nd[rt*2+1].s00);
nd[rt].s00=mx(nd[rt].s00,nd[rt*2].s00);
nd[rt].s00=mx(nd[rt].s00,nd[rt*2+1].s00);
nd[rt].s01=mx(nd[rt*2].s00+nd[rt*2+1].s11,nd[rt*2].s01+nd[rt*2+1].s01);
nd[rt].s01=mx(nd[rt].s01,nd[rt*2].s01);
nd[rt].s01=mx(nd[rt].s01,nd[rt*2+1].s01);
nd[rt].s10=mx(nd[rt*2].s10+nd[rt*2+1].s10,nd[rt*2].s11+nd[rt*2+1].s00);
nd[rt].s10=mx(nd[rt].s10,nd[rt*2].s10);
nd[rt].s10=mx(nd[rt].s10,nd[rt*2+1].s10);
nd[rt].s11=mx(nd[rt*2].s10+nd[rt*2+1].s11,nd[rt*2].s11+nd[rt*2+1].s01);
nd[rt].s11=mx(nd[rt].s11,nd[rt*2].s11);
nd[rt].s11=mx(nd[rt].s11,nd[rt*2+1].s11);
}
void build(int rt,int l,int r)
{
if(l==r){
if(l%2){
nd[rt].s11=f[l];
nd[rt].s01=nd[rt].s10=nd[rt].s00=-inf;
}
else {
nd[rt].s00=f[l];
nd[rt].s01=nd[rt].s10=nd[rt].s11=-inf;
}
return;
}
int mid=(l+r)>>1;
build(rt*2,l,mid);
build(rt*2+1,mid+1,r);
setnd(rt);
}
void update(int rt,int l,int r,int a,int b){
if(l==r){
f[l]=b;
if(l%2){
nd[rt].s11=f[l];
nd[rt].s01=nd[rt].s10=nd[rt].s00=-inf;
}
else {
nd[rt].s00=f[l];
nd[rt].s01=nd[rt].s10=nd[rt].s11=-inf;
}
return;
}
int mid=(l+r)>>1;
if(a<=mid) update(rt*2,l,mid,a,b);
else update(rt*2+1,mid+1,r,a,b);
setnd(rt);
}
Node query(int rt,int l,int r,int lx,int rx)
{
if(lx==l&&rx==r){
return nd[rt];
}
int mid=(l+r)>>1;
if(rx<=mid) return query(rt*2,l,mid,lx,rx);
else if(lx>mid) return query(rt*2+1,mid+1,r,lx,rx);
else{
Node sl=query(rt*2,l,mid,lx,mid);
Node sr=query(rt*2+1,mid+1,r,mid+1,rx);
Node p;
p.s00=mx(sl.s00+sr.s10,sl.s01+sr.s00);
p.s00=mx(p.s00,sl.s00);
p.s00=mx(p.s00,sr.s00);
p.s01=mx(sl.s00+sr.s11,sl.s01+sr.s01);
p.s01=mx(p.s01,sl.s01);
p.s01=mx(p.s01,sr.s01);
p.s10=mx(sl.s10+sr.s10,sl.s11+sr.s00);
p.s10=mx(p.s10,sl.s10);
p.s10=mx(p.s10,sr.s10);
p.s11=mx(sl.s10+sr.s11,sl.s11+sr.s01);
p.s11=mx(p.s11,sl.s11);
p.s11=mx(p.s11,sr.s11);
return p;
}
}
int main()
{
rd(t);
while(t--){
rd2(n,m);
for(int i=1;i<=n;i++)
rd(f[i]);
build(1,1,n);
for(int i=1;i<=m;i++)
{
rd(q);
rd2(a,b);
if(q) update(1,1,n,a,b);
else {
Node p=query(1,1,n,a,b);
printf("%I64d\n",mx(mx(p.s00,p.s01),mx(p.s10,p.s11)));
}
}
}
return 0;
}