題意:
給出兩種操作,一種是求區間漂亮子序列的和的最大值,另一個就是給指定的點改變值。
題目中最重要的一句話:A beautiful subsequence is a subsequence that all the adjacent pairs of elves in the sequence have a different parity of position.
翻譯:一個漂亮的子序列是指所有相鄰的點在原序列中的奇偶性交替出現。
這就是問題的關鍵,否則還以爲是裸線段樹呢,多校題不會醬紫吧。。
好了,那既然需要奇偶性,那就用一個is[]表示,is[i]==1表示該點是奇,is[i]==0表示該點是偶。
因爲每個區間我們不確定是九,還是偶奇,還是奇奇,還是偶偶。所以我們把這些可能的性質都放入struct中來標記,最終只有一個真實的有效。
ps:頂好的線段樹模板啊OUuUO~
AC代碼:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <queue>
#include <algorithm>
using namespace std;
#define read freopen("q.in","r",stdin)
#define LL long long
const LL inf =-100000000000000000;
const int maxn = 100005;
struct Node
{
LL oo,oe,eo,ee;//表示該區間的奇偶性
void init()
{
oo=ee=oe=eo=inf;
}
}node[maxn*4];
int is[maxn*4];//判斷點在原數組中的奇偶性
int cnt;
Node Max(Node a,Node b)
{
Node c;
c.oo=max(a.oo,b.oo);
c.oo=max(c.oo,a.oe+b.oo);
c.oo=max(c.oo,a.oo+b.eo);
c.oo=max(c.oo,inf);
c.ee=max(a.ee,b.ee);
c.ee=max(c.ee,a.ee+b.oe);
c.ee=max(c.ee,a.eo+b.ee);
c.ee=max(c.ee,inf);
c.eo=max(a.eo,b.eo);
c.eo=max(c.eo,a.ee+b.oo);
c.eo=max(c.eo,a.eo+b.eo);
c.eo=max(c.eo,inf);
c.oe=max(a.oe,b.oe);
c.oe=max(c.oe,a.oe+b.oe);
c.oe=max(c.oe,a.oo+b.ee);
c.oe=max(c.oe,inf);
return c;
}
void PushUp(int rt)
{
node[rt]=Max(node[rt<<1],node[rt<<1|1]);
}
void build(int l,int r,int rt)
{
if(l==r)
{
node[rt].init();
if(cnt&1)
{
is[rt]=1;
scanf("%I64d",&node[rt].oo);
}
else
{
is[rt]=0;
scanf("%I64d",&node[rt].ee);
}
cnt++;
return ;
}
int mid=(l+r)/2;
build(l,mid,rt<<1);
build(mid+1,r,rt<<1|1);
PushUp(rt);
}
void Update(int p,int c,int l,int r,int rt)
{
if(l==r && p==l)
{
if(is[rt]==1)
node[rt].oo=c;
else node[rt].ee=c;
return ;
}
int mid=(l+r)/2;
if(p<=mid)Update(p,c,l,mid,rt<<1);
else Update(p,c,mid+1,r,rt<<1|1);
PushUp(rt);
}
Node Query(int L,int R,int l,int r,int rt)
{
if(L<=l && r<=R)
return node[rt];
int mid=(l+r)/2;
Node res;
res.init();
if(L<=mid)res=Max(res,Query(L,R,l,mid,rt<<1));
if(R>mid)res=Max(res,Query(L,R,mid+1,r,rt<<1|1));
return res;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,m,i,j;
int op,a,b;
cnt=1;
memset(is,0,sizeof(is));
memset(node,0,sizeof(node));
scanf("%d%d",&n,&m);
build(1,n,1);
for(i=0;i<m;i++)
{
scanf("%d%d%d",&op,&a,&b);
if(op==0)
{
Node c=Query(a,b,1,n,1);
LL res=max(max(c.oo,c.ee),max(c.oe,c.eo));
cout<<res<<endl;
}
else Update(a,b,1,n,1);
}
}
}