时间限制: 9 Sec 内存限制: 64 MB
题目描述
有n个整数,两种操作方式:
0 x y:查询[x,y]区间的最大子序列和,其中子序列中相邻元素的原下标奇偶性都不同。
1 x y:将x位置的数改成y。
输入
第一行一个整数T,表示测试点的个数。
对于每个测试点:
第一行两个整数n和m(n,m <= 100000),分别表示序列的长度和操作的次数。
第二行包含n个整数,a1,…,an(-1000000000 ≤ai≤1000000000)。
接下来m行,每行代表一次操作,包含3个整数:type x y。
当type=0时,输出[x,y]区间的最大子序列和,其中(1 <= a <= b <= n)。
当type=1时,将x位置的数改成y,其中(1 <= a <= n, 1 <= b <= 1e9)。
输出
对于每个操作0,请输出相应查询的答案。
样例输入
1
1 1
1
0 1 1
样例输出
1
来源
2015多校
用线段树分别维护奇数位开始偶数位结束,奇数位开始奇数位结束,偶数位开始偶数位结束,偶数位开始奇数位结束四个值即可。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#define N 100010
#define ll long long
#define inf 999999999999999999ll
using namespace std;
int Q,n,m,s[N];
struct node{ll sum1,sum2,sum3,sum4;}t[N*4];
//积积,积偶,偶积,偶偶
class seg_tree
{
void update(int x)
{
int lc=x<<1,rc=lc+1;
t[x].sum1=max(t[lc].sum1+t[rc].sum3,max(t[lc].sum2+t[rc].sum1,max(t[lc].sum1,t[rc].sum1)));
t[x].sum2=max(t[lc].sum1+t[rc].sum4,max(t[lc].sum2+t[rc].sum2,max(t[lc].sum2,t[rc].sum2)));
t[x].sum3=max(t[lc].sum3+t[rc].sum3,max(t[lc].sum4+t[rc].sum1,max(t[lc].sum3,t[rc].sum3)));
t[x].sum4=max(t[lc].sum3+t[rc].sum4,max(t[lc].sum4+t[rc].sum2,max(t[lc].sum4,t[rc].sum4)));
}
public:
void build(int x,int l,int r)
{
t[x].sum1=-inf;t[x].sum2=-inf;
t[x].sum3=-inf;t[x].sum4=-inf;
if(l==r)
{
if(l&1)t[x].sum1=(ll)s[l];
else t[x].sum4=(ll)s[l];return;
}
int mid=l+r>>1,lc=x<<1,rc=lc+1;
build(lc,l,mid);build(rc,mid+1,r);update(x);
}
void modify(int x,int l,int r,int des,int num)
{
if(l==r)
{
if(l&1)t[x].sum1=(ll)num;
else t[x].sum4=(ll)num;return;
}
int mid=l+r>>1,lc=x<<1,rc=lc+1;
if(des<=mid)modify(lc,l,mid,des,num);
else modify(rc,mid+1,r,des,num);update(x);
}
node qry(int x,int l,int r,int ql,int qr)
{
if(ql==l&&r==qr)return t[x];
int mid=l+r>>1,lc=x<<1,rc=lc+1;
if(qr<=mid)return qry(lc,l,mid,ql,qr); if(ql>mid)return qry(rc,mid+1,r,ql,qr);
node t1=qry(lc,l,mid,ql,mid),t2=qry(rc,mid+1,r,mid+1,qr),res;
res.sum1=max(t1.sum1+t2.sum3,max((t1.sum2+t2.sum1),max(t1.sum1,t2.sum1)));
res.sum2=max(t1.sum1+t2.sum4,max((t1.sum2+t2.sum2),max(t1.sum2,t2.sum2)));
res.sum3=max(t1.sum3+t2.sum3,max((t1.sum4+t2.sum1),max(t1.sum3,t2.sum3)));
res.sum4=max(t1.sum3+t2.sum4,max((t1.sum4+t2.sum2),max(t1.sum4,t2.sum4)));
return res;
}
}T;
int main()
{
int type,a,b;
scanf("%d",&Q);
while(Q--)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&s[i]);
T.build(1,1,n);
while(m--)
{
scanf("%d%d%d",&type,&a,&b);
if(type)T.modify(1,1,n,a,b);
else
{
node p=T.qry(1,1,n,a,b);
printf("%lld\n",max(p.sum4,max(p.sum3,max(p.sum1,p.sum2))));
}
}
}
return 0;
}