链接:http://acm.hdu.edu.cn/showproblem.php?pid=5316

1 1 1 1 0 1 1
1
题意:有n个数,两个操作,0操作,输出l到r ,所有奇偶交替 的子序列中,值的最大和。(自序列是可以不用连续的)。 1操作是把a位置的数改成b。
做法:维护区间内的
jiou, 这个区间以奇数位开始,偶数位结束的 所有子序列中的最大和。
ouji,jiji,ouou 三个数同理。
#include <cstdio>
#include <algorithm>
#include <stdio.h>
#include <string.h>
using namespace std;
 
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
#define LL __int64
#define inf -100000000000000000
const int maxn = 111111;
struct point 
{
    __int64 jiji,ouou,jiou,ouji;
};
point pp[maxn<<2]; 
int jiou[maxn<<2];
point big(point a,point b)
{
    point c;
    c.jiji=max(a.jiji,b.jiji);
    c.jiji=max(c.jiji,a.jiji+b.ouji);
    c.jiji=max(c.jiji,a.jiou+b.jiji);
    c.jiji=max(c.jiji,inf);
    c.jiou=max(a.jiou,b.jiou);
    c.jiou=max(c.jiou,a.jiji+b.ouou);
    c.jiou=max(c.jiou,a.jiou+b.jiou);
    c.jiou=max(c.jiou,inf);
    c.ouji=max(a.ouji,b.ouji);
    c.ouji=max(c.ouji,a.ouji+b.ouji);
    c.ouji=max(c.ouji,a.ouou+b.jiji);
    c.ouji=max(c.ouji,inf);
    c.ouou=max(a.ouou,b.ouou);
    c.ouou=max(c.ouou,a.ouji+b.ouou);
    c.ouou=max(c.ouou,a.ouou+b.jiou);
    c.ouou=max(c.ouou,inf);
    return c;
}
void PushUp(int rt) {
    pp[rt]=big(pp[rt<<1],pp[rt<<1|1]);
}
int kk=1;
void build(int l,int r,int rt) {
    if (l == r) {
        if(kk&1)
        {
            jiou[rt]=1;
            scanf("%I64d",&pp[rt].jiji);
            pp[rt].ouou=inf;
            pp[rt].ouji=inf;
            pp[rt].jiou=inf;
        }
        else
        {
            jiou[rt]=0;
            scanf("%I64d",&pp[rt].ouou);
            pp[rt].jiou=pp[rt].jiji=pp[rt].ouji=inf;
        }
        kk++;
        return ;
    }
    int m = (l + r) >> 1;
    build(lson);
    build(rson);
    PushUp(rt);
}
void update(int L,int c,int l,int r,int rt) {
    if (l==r&&l==L) { 
        if(jiou[rt]==1)
            pp[rt].jiji=c;
        if(jiou[rt]==0)
            pp[rt].ouou=c;
        return ;
    }
    int m = (l + r) >> 1;
    if (L <= m) update(L , c , lson);
    else
        update(L  , c , rson);
    PushUp(rt);
}
point query(int L,int R,int l,int r,int rt) {
    if (L <= l && r <= R) { 
        return pp[rt];
    }
    int m = (l + r) >> 1;
    if(L<=m&&m<R)  return big( query(L , R , lson),query(L , R , rson));
    if(L<=m) return query(L , R , lson);
    if(m<R) return query(L , R , rson);
      
}
int main() {
    int t;
    int n,q;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&q);
        kk=1;
        if(n)
        build(1 , n , 1);
        while(q--)
        {
            int op; 
            int a,b;
            scanf("%d",&op);
            scanf("%d%d",&a,&b);
            if(n==0)
            {
                if(op==0)
                    puts("0"); 
                continue;
            }
            
            if(op==0)
            {
                if(a>b)
                    swap(a,b);
                point ppp=query(a,b,1,n,1);
                printf("%I64d\n",max(ppp.jiji,max(ppp.jiou,max(ppp.ouji,ppp.ouou))));
            }
            else
                update(a , b , 1 , n , 1);
        } 
    } 
    return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文:http://blog.csdn.net/u013532224/article/details/47109575