//15多校第三场1001
//线段树 奇偶区间合并
//保证00、01、10、11分别维护的是偶偶,偶奇,奇偶,奇奇开头结尾的区间最大值
#include<cstdio>
#include<algorithm>
using namespace::std;
typedef long long LL;
const int N = 100010;
const int INF=-0x7fffffff;
#define lson 2*o,l,mid
#define rson 2*o+1,mid+1,r
LL a[N];
LL tree[4*N][2][2];
struct node{
LL X[2][2];
};
void pushup(int o){
tree[o][0][0]=max(tree[2*o][0][0],tree[2*o+1][0][0]);//不合并
tree[o][0][0]=max(tree[o][0][0],tree[2*o][0][0]+tree[2*o+1][1][0]);//左儿子偶偶,右儿子奇偶
tree[o][0][0]=max(tree[o][0][0],tree[2*o][0][1]+tree[2*o+1][0][0]);//左儿子偶奇,右儿子偶偶
tree[o][0][1]=max(tree[2*o][0][1],tree[2*o+1][0][1]);//不合并
tree[o][0][1]=max(tree[o][0][1],tree[2*o][0][0]+tree[2*o+1][1][1]);//左儿子偶偶,右儿子奇奇
tree[o][0][1]=max(tree[o][0][1],tree[2*o][0][1]+tree[2*o+1][0][1]);//左儿子偶奇,右儿子偶奇
tree[o][1][0]=max(tree[2*o][1][0],tree[2*o+1][1][0]);//不合并
tree[o][1][0]=max(tree[o][1][0],tree[2*o][1][0]+tree[2*o+1][1][0]);//左儿子奇偶,右儿子奇偶
tree[o][1][0]=max(tree[o][1][0],tree[2*o][1][1]+tree[2*o+1][0][0]);//左儿子奇奇,右儿子偶偶
tree[o][1][1]=max(tree[2*o][1][1],tree[2*o+1][1][1]);//不合并
tree[o][1][1]=max(tree[o][1][1],tree[2*o][1][0]+tree[2*o+1][1][1]);//左儿子奇偶,右儿子奇奇
tree[o][1][1]=max(tree[o][1][1],tree[2*o][1][1]+tree[2*o+1][0][1]);//左儿子奇奇,右儿子偶奇
}
void build(int o,int l,int r){
if(l>r)return;
if(l==r){
if(l&1){
tree[o][1][1]=a[l];
tree[o][1][0]=tree[o][0][0]=tree[o][0][1]=INF;
}
else{
tree[o][0][0]=a[l];
tree[o][1][0]=tree[o][1][1]=tree[o][0][1]=INF;
}
return ;
}
int mid=(l+r)>>1;
build(lson);build(rson);
pushup(o);
}
node query(int o,int l,int r,int a,int b){
node p;
p.X[0][0]=p.X[0][1]=p.X[1][0]=p.X[1][1]=INF;
if(a>r||b<l)return p;
if(a<=l&&r<=b){
p.X[0][0]=tree[o][0][0];
p.X[0][1]=tree[o][0][1];
p.X[1][0]=tree[o][1][0];
p.X[1][1]=tree[o][1][1];
return p;//不知道哪个最优
}
int mid=(l+r)>>1;
if(r<=mid)return query(lson,a,b);
else if(l>mid)return query(rson,a,b);
else{
node L=query(lson,a,b);
node R=query(rson,a,b);
p.X[0][0]=max(max(max(L.X[0][0]+R.X[1][0],L.X[0][1]+R.X[0][0]),L.X[0][0]),R.X[0][0]);
p.X[0][1]=max(max(max(L.X[0][1]+R.X[0][1],L.X[0][0]+R.X[1][1]),L.X[0][1]),R.X[0][1]);
p.X[1][0]=max(max(max(L.X[1][0]+R.X[1][0],L.X[1][1]+R.X[0][0]),L.X[1][0]),R.X[1][0]);
p.X[1][1]=max(max(max(L.X[1][0]+R.X[1][1],L.X[1][1]+R.X[0][1]),L.X[1][1]),R.X[1][1]);
return p;
}
}
void update(int o,int l,int r,int pos,int x){
if(pos<l||pos>r||l>r)return;
if(l==r&&l==pos){
if(l&1){
tree[o][1][1]=x;
}
else {
tree[o][0][0]=x;
}
return ;
}
int mid=(l+r)>>1;
update(lson,pos,x);
update(rson,pos,x);
pushup(o);
}
int main(){
int t;
scanf("%d",&t);
while(t--){
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
build(1,1,n);
int kind;
while(m--){
scanf("%d",&kind);
if(kind==0){
int l,r;
scanf("%d%d",&l,&r);
node p=query(1,1,n,l,r);
printf("%lld\n",max(max(max(p.X[0][0],p.X[0][1]),p.X[1][0]),p.X[1][1]));
}
else{
int x,y;
scanf("%d%d",&x,&y);
update(1,1,n,x,y);
}
}
}
return 0;
}
hdu5316 Magician(15多校第三场1001)(线段树)
最新推荐文章于 2020-05-22 13:27:07 发布