码迷,mamicode.com
首页 > 其他好文 > 详细

[线段树]hdu5316

时间:2015-08-16 23:05:59      阅读:142      评论:0      收藏:0      [点我收藏+]

标签:线段树

题意:
给出两种操作,一种是求区间漂亮子序列的和的最大值,另一个就是给指定的点改变值。
题目中最重要的一句话:A beautiful subsequence is a subsequence that all the adjacent pairs of elves in the sequence have a different parity of position.
翻译:一个漂亮的子序列是指所有相邻的点在原序列中的奇偶性交替出现。
这就是问题的关键,否则还以为是裸线段树呢,多校题不会酱紫吧。。
好了,那既然需要奇偶性,那就用一个is[]表示,is[i]==1表示该点是奇,is[i]==0表示该点是偶。
因为每个区间我们不确定是九,还是偶奇,还是奇奇,还是偶偶。所以我们把这些可能的性质都放入struct中来标记,最终只有一个真实的有效。

ps:顶好的线段树模板啊OUuUO~

AC代码:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <vector>
#include <stack>
#include <map>
#include <queue>
#include <algorithm>
using namespace std;

#define read freopen("q.in","r",stdin)
#define LL long long

const LL inf =-100000000000000000;
const int maxn = 100005;
struct Node
{
    LL oo,oe,eo,ee;//表示该区间的奇偶性 
    void init()
    {
        oo=ee=oe=eo=inf;
    }
}node[maxn*4]; 
int is[maxn*4];//判断点在原数组中的奇偶性
int cnt;
Node Max(Node a,Node b)
{
    Node c;
    c.oo=max(a.oo,b.oo);
    c.oo=max(c.oo,a.oe+b.oo);
    c.oo=max(c.oo,a.oo+b.eo);
    c.oo=max(c.oo,inf);

    c.ee=max(a.ee,b.ee);
    c.ee=max(c.ee,a.ee+b.oe);
    c.ee=max(c.ee,a.eo+b.ee);
    c.ee=max(c.ee,inf);

    c.eo=max(a.eo,b.eo);
    c.eo=max(c.eo,a.ee+b.oo);
    c.eo=max(c.eo,a.eo+b.eo);
    c.eo=max(c.eo,inf);

    c.oe=max(a.oe,b.oe);
    c.oe=max(c.oe,a.oe+b.oe);
    c.oe=max(c.oe,a.oo+b.ee);
    c.oe=max(c.oe,inf);

    return c;
}
void PushUp(int rt)
{
    node[rt]=Max(node[rt<<1],node[rt<<1|1]); 
}


void build(int l,int r,int rt)
{
    if(l==r)
    {
        node[rt].init();
        if(cnt&1)
        {
            is[rt]=1;
            scanf("%I64d",&node[rt].oo);
        }
        else
        {
            is[rt]=0;
            scanf("%I64d",&node[rt].ee);
        }
        cnt++;
        return ;
    }
    int mid=(l+r)/2;
    build(l,mid,rt<<1);
    build(mid+1,r,rt<<1|1);
    PushUp(rt);
 } 

void Update(int p,int c,int l,int r,int rt)
{
    if(l==r && p==l)
    {
        if(is[rt]==1)
            node[rt].oo=c;
        else node[rt].ee=c;
        return ;
    }
    int mid=(l+r)/2;
    if(p<=mid)Update(p,c,l,mid,rt<<1);
    else Update(p,c,mid+1,r,rt<<1|1);

    PushUp(rt);
}

Node Query(int L,int R,int l,int r,int rt)
{
    if(L<=l && r<=R)
        return node[rt];
    int mid=(l+r)/2;

    Node res;
    res.init();
    if(L<=mid)res=Max(res,Query(L,R,l,mid,rt<<1));
    if(R>mid)res=Max(res,Query(L,R,mid+1,r,rt<<1|1));

    return res;
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,m,i,j;
        int op,a,b;
        cnt=1;
        memset(is,0,sizeof(is));
        memset(node,0,sizeof(node));
        scanf("%d%d",&n,&m);
        build(1,n,1);
        for(i=0;i<m;i++)
        {
            scanf("%d%d%d",&op,&a,&b);
            if(op==0)
            {
                Node c=Query(a,b,1,n,1);
                LL res=max(max(c.oo,c.ee),max(c.oe,c.eo));
                cout<<res<<endl;
            }
            else Update(a,b,1,n,1);
        }
    }
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

[线段树]hdu5316

标签:线段树

原文地址:http://blog.csdn.net/u010582475/article/details/47708155

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!