【線段樹】 HDU 5316 Magician

點擊打開鏈接

題意:求一個區間內的最大的子序列的和:要求必須下標奇偶奇偶。。不能出現奇奇 偶偶這樣

維護好

開始爲奇結束爲偶

開始爲奇結束爲奇

開始爲偶結束爲偶

開始爲偶結束爲奇

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <cmath>
using namespace std;
#include <queue>
#include <stack>
#include <vector>
#include <deque>
#define cler(arr, val)    memset(arr, val, sizeof(arr))
#define FOR(i,a,b)  for(int i=a;i<=b;i++)
#define IN   freopen ("in.txt" , "r" , stdin);
#define OUT  freopen ("out.txt" , "w" , stdout);
typedef long long  LL;
const int MAXN = 101000;
const int MAXM = 200000;
const int INF = 0x3f3f3f3f;
const int mod = 1000000007;
const double eps= 1e-8;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
LL num[MAXN];
struct Node
{
    LL jo,jj,oo,oj;
}node[MAXN<<2];
void pushup(int rt)
{
    node[rt].jo=max(node[rt<<1].jo,node[rt<<1|1].jo);
    node[rt].jo=max(node[rt].jo,node[rt<<1].jo+node[rt<<1|1].jo);
    node[rt].jo=max(node[rt].jo,node[rt<<1].jj+node[rt<<1|1].oo);
    node[rt].jj=max(node[rt<<1].jj,node[rt<<1|1].jj);
    node[rt].jj=max(node[rt].jj,node[rt<<1].jo+node[rt<<1|1].jj);
    node[rt].jj=max(node[rt].jj,node[rt<<1].jj+node[rt<<1|1].oj);
    node[rt].oo=max(node[rt<<1].oo,node[rt<<1|1].oo);
    node[rt].oo=max(node[rt].oo,node[rt<<1].oo+node[rt<<1|1].jo);
    node[rt].oo=max(node[rt].oo,node[rt<<1].oj+node[rt<<1|1].oo);
    node[rt].oj=max(node[rt<<1].oj,node[rt<<1|1].oj);
    node[rt].oj=max(node[rt].oj,node[rt<<1].oo+node[rt<<1|1].jj);
    node[rt].oj=max(node[rt].oj,node[rt<<1].oj+node[rt<<1|1].oj);
}
void build(int l,int r,int rt)
{
    if(l==r)
    {
        if(l%2==1)
        {
            node[rt].jj=num[l];
            node[rt].jo=-INF;
            node[rt].oj=-INF;
            node[rt].oo=-INF;
        }
        else
        {
            node[rt].jj=-INF;
            node[rt].jo=-INF;
            node[rt].oj=-INF;
            node[rt].oo=num[l];
        }
        return ;
    }
    int m=(l+r)>>1;
    build(lson);
    build(rson);
    pushup(rt);
}
Node query(int L,int R,int l,int r,int rt)
{
    if(L<=l&&r<=R)
        return node[rt];
    int m=(l+r)>>1;
    Node ll={-INF,-INF,-INF,-INF};
    Node rr={-INF,-INF,-INF,-INF},tmp;
    if(L<=m)
    {
        ll=query(L,R,lson);
    }
    if(m<R)
    {
        rr=query(L,R,rson);
    }
    tmp.jj=max(ll.jj,rr.jj);
    tmp.jj=max(tmp.jj,ll.jj+rr.oj);
    tmp.jj=max(tmp.jj,ll.jo+rr.jj);
    tmp.jo=max(ll.jo,rr.jo);
    tmp.jo=max(tmp.jo,ll.jj+rr.oo);
    tmp.jo=max(tmp.jo,ll.jo+rr.jo);
    tmp.oo=max(ll.oo,rr.oo);
    tmp.oo=max(tmp.oo,ll.oj+rr.oo);
    tmp.oo=max(tmp.oo,ll.oo+rr.jo);
    tmp.oj=max(ll.oj,rr.oj);
    tmp.oj=max(tmp.oj,ll.oj+rr.oj);
    tmp.oj=max(tmp.oj,ll.oo+rr.jj);
    return tmp;
}
int update(int x,int val,int l,int r,int rt)
{
    if(l==r)
    {
        if(x%2==1)
        {
            node[rt].jj=val;
            node[rt].jo=node[rt].oj=node[rt].oo=-INF;
        }
        else
        {
            node[rt].oo=val;
            node[rt].jo=node[rt].oj=node[rt].jj=-INF;
        }
        return 0;
    }
    int m=(l+r)>>1;
    if(x <= m) update(x,val,lson);
    else update(x,val,rson);
    pushup(rt);
}
int main()
{
    int m,n,t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%I64d",&num[i]);
        build(1,n,1);
        for(int i=0;i<m;i++)
        {
            int ls,rs,op;
            scanf("%d%d%d",&op,&ls,&rs);
            if(op==0)
            {
                Node ans=query(ls,rs,1,n,1);

                printf("%I64d\n",max(ans.oj,max(ans.oo,max(ans.jj,ans.jo))));
            }
            else
                update(ls,rs,1,n,1);
        }
    }
    return 0;
}
/*
1
10 5
10 1 2 3 4 -5 6 7 8 9 10
0 1 10
1 4 -5
0 1 10
1 10 -1
0 1 10

*/


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章