HDU 5316

HDU 5316

題意是給一個數列,有兩種操作,一是詢問[L,R]的最大子序列和,二是改變某個位置的值。單點修改,區間查詢,很顯然的線段樹。關鍵在於,詢問時的最大子序列要求相鄰元素的在原序列中的位置奇偶性不同。
序列的奇偶性根據首位和末位的奇偶性最多就四種情況,奇奇,偶偶,奇偶,偶奇。
那麼線段樹中的每個節點保存這四種序列的最大和即可,並注意合併。

#include<bits/stdc++.h>
#define LS (root<<1)
#define RS ((root<<1)|1)
#define LSON LS,l,mid
#define RSON RS,(mid+1),r
#define MID mid=((l+r)/2)
#define LL long long
#define mm(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn=1e5+5;
const LL Inf=1e18;
struct sum{
    LL odd_odd, odd_even, even_odd, even_even;
    sum(){odd_odd=-Inf; odd_even=-Inf; even_odd=-Inf; even_even=-Inf;}
};
sum s[maxn<<2];
LL a[maxn];
void pushup(int root){
    s[root].odd_odd=max(max(s[LS].odd_odd, s[RS].odd_odd), max(s[LS].odd_odd+s[RS].even_odd, s[LS].odd_even+s[RS].odd_odd));
    s[root].odd_even=max(max(s[LS].odd_even, s[RS].odd_even), max(s[LS].odd_odd+s[RS].even_even, s[LS].odd_even+s[RS].odd_even));
    s[root].even_odd=max(max(s[LS].even_odd, s[RS].even_odd), max(s[LS].even_odd+s[RS].even_odd, s[LS].even_even+s[RS].odd_odd));
    s[root].even_even=max(max(s[LS].even_even, s[RS].even_even), max(s[LS].even_even+s[RS].odd_even, s[LS].even_odd+s[RS].even_even));
}
void build(int root,int l,int r){
    s[root].odd_odd=s[root].odd_even=s[root].even_odd=s[root].even_even=-Inf;
    if(l==r){
        if(l%2)
            s[root].odd_odd=a[l];
        else
            s[root].even_even=a[l];
        return;
    }
    int mid=(l+r)>>1;
    build(LSON);
    build(RSON);
    pushup(root);
}
void update(int root,int l,int r,int pos,LL v){
    if(l==r){
        if(l%2)
            s[root].odd_odd=v;
        else
            s[root].even_even=v;
        return;
    }
    int mid=(l+r)>>1;
    if(pos<=mid) update(LSON, pos, v);
    else update(RSON, pos, v);
    pushup(root);
}
sum unite(sum lsum, sum rsum){
    sum ret;
    ret.odd_odd=max(max(lsum.odd_odd, rsum.odd_odd), max(lsum.odd_odd+rsum.even_odd, lsum.odd_even+rsum.odd_odd));
    ret.odd_even=max(max(lsum.odd_even, rsum.odd_even), max(lsum.odd_even+rsum.odd_even, lsum.odd_odd+rsum.even_even));
    ret.even_odd=max(max(lsum.even_odd, rsum.even_odd), max(lsum.even_odd+rsum.even_odd, lsum.even_even+rsum.odd_odd));
    ret.even_even=max(max(lsum.even_even, rsum.even_even), max(lsum.even_even+rsum.odd_even, lsum.even_odd+rsum.even_even));
    return ret;
}
sum query(int root,int l,int r,int L,int R){
    if(L<=l&&r<=R){
        return s[root];
    }
    int mid=(l+r)>>1;
    sum lsum, rsum;
    if(L<=mid) lsum=query(LSON, L, R);
    if(R>mid) rsum=query(RSON, L, R);
    return unite(lsum,rsum);
}
int main(){
    int T, n, m;
    int op, L, R;
    LL v;

    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n, &m);
        for(int i=1;i<=n;i++)
            scanf("%lld",&a[i]);
        build(1,1,n);
        for(int i=0;i<m;i++){
            scanf("%d",&op);
            if(op==0){
                scanf("%d%d", &L, &R);
                sum ans=query(1,1,n,L,R);
                printf("%lld\n",max(max(ans.odd_odd, ans.odd_even), max(ans.even_even, ans.even_odd)));
            }else{
                scanf("%d%lld",&L, &v);
                update(1,1,n,L,v);
            }
        }
    }

    return 0;
}
發佈了54 篇原創文章 · 獲贊 3 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章