HDU 5316 Magician

【题意】
  • 给一个 n(n<=1e5)
  • 长度的数列有两种操作
  • 1 :修改一个点
  • 2 :查询一个区间,查询一个最大子序列,子序列需满足下标奇偶交替,比方说 1,4,5,6 ,或者 4,5,6

【分析】

         奇偶交替的序列无非四种情况

  • 奇开头偶结尾
  • 奇开头奇结尾
  • 偶开头奇结尾
  • 偶开头偶结尾

        然后我就可以存这四个东西了,以 o

        表示 odd e 表示 even
        所以我取名就是 oo,ee,oe,eo

【AC代码】

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 100005;
int A[maxn];
struct seg_tree{
    struct node{
        int l,r;
        ll oo,oe,eo,ee;
    }Tree[maxn<<2];
    node Push_Up(node a,node b){
        node res;
        res.l=a.l,res.r=b.r;
        res.oo = max(max(a.oo,b.oo),max(a.oo+b.eo,a.oe+b.oo));
        res.oe = max(max(a.oe,b.oe),max(a.oe+b.oe,a.oo+b.ee));
        res.eo = max(max(a.eo,b.eo),max(a.ee+b.oo,a.eo+b.eo));
        res.ee = max(max(a.ee,b.ee),max(a.eo+b.ee,a.ee+b.oe));
        return res;
    }
    void Build(int l,int r,int rt){
        Tree[rt].l=l,Tree[rt].r=r;
        Tree[rt].oo=Tree[rt].oe=Tree[rt].eo=Tree[rt].ee=-1e12;
        if(l==r) return ;
        int m = (Tree[rt].l+Tree[rt].r)>>1;
        Build(l,m,rt<<1);
        Build(m+1,r,rt<<1|1);
        Tree[rt]=Push_Up(Tree[rt<<1],Tree[rt<<1|1]);
    }
    void update(int pos,int val,int rt){
        if(Tree[rt].l==pos&&Tree[rt].r==pos){
            if(pos%2) Tree[rt].oo = val;
            else      Tree[rt].ee = val;
            return ;
        }
        int m =(Tree[rt].l+Tree[rt].r)>>1;
        if(m>=pos) update(pos,val,rt<<1);
        else if(m<pos) update(pos,val,rt<<1|1);
        Tree[rt] = Push_Up(Tree[rt<<1],Tree[rt<<1|1]);
    }
    node query_ans(int L,int R,int rt){
        if(L==Tree[rt].l&&Tree[rt].r==R){
            return Tree[rt];
        }
        int m = (Tree[rt].l+Tree[rt].r)>>1;
        if(R<=m) return query_ans(L,R,rt<<1);
        else if(m<L)  return query_ans(L,R,rt<<1|1);
        else
            return Push_Up(query_ans(L,m,rt<<1),query_ans(m+1,R,rt<<1|1));
    }
}tree;
int main(){
    int T,n,q;
    while(~scanf("%d",&T))
    {
        while(T--){
        scanf("%d%d",&n,&q);
        tree.Build(1,n,1);
        for(int i=1; i<=n; i++){
            scanf("%d",&A[i]);
            tree.update(i,A[i],1);
        }
        while(q--){
            int op,a,b;
            scanf("%d%d%d",&op,&a,&b);
            if(op==0){
                auto temp = tree.query_ans(a,b,1);
                ll ans = max(max(temp.oo,temp.ee),max(temp.oe,temp.eo));
                printf("%I64d\n",ans);
            }else{
                tree.update(a,b,1);
            }
        }
    }
    }
    return 0;
}


你可能感兴趣的:(HDU 5316 Magician)