1001. Magician (hdu5316)

这个题目用到线段树来合并区间,题目有句话的意思A beautiful subsequence is a subsequence that all the adjacent pairs of elves in the sequence have a different parity of position说的是相邻的两个元素必须有不同的奇偶位置,所有一个序列有四种可能的形式,奇...奇, 奇...偶,偶...奇, 偶...偶,这四种形式只是端点的奇偶性,所以线段树的每个节点就得有四个值,分别维护这四个值就行了,举个例子来说,根节点的偶偶的最大值取决于 左孩子的偶偶 + 右孩子的奇偶, 左孩子的偶奇 + 右孩子的偶偶, 左孩子的偶偶,右孩子的偶偶, 所以根节点的偶偶就等于他们当中的最大值,同理,其他的三个也是这样,剩下的另外一种操作就是更新点了。

#include<iostream>
#include <stdio.h>
using namespace std;
typedef long long LL;
const int maxn = 100010;
const LL inf = 1LL << 61;
LL d[maxn];
struct Data{
    LL s00, s01, s10, s11;//s00表示偶偶, s01表示偶奇, s10表示奇偶,s11表示奇奇
    void init()
    {
        s00 = s01 = s10 = s11 = -inf;//初始化一定要为负无穷,因为可能有负数
    }
    LL max_ele()
    {
        return max(max(s00, s01), max(s10, s11));//找出他们当中最大的
    }
};
struct tree{
    Data data;
};
tree sum[maxn * 4];//线段树
void checkmax(LL &a, const LL b)
{
    if (a < b)
        a = b;
}
Data operator + (const Data &a, const Data &b)
{
    Data ret;
    ret.s11 = max(a.s11 + b.s01, a.s10 + b.s11); checkmax(ret.s11, a.s11); checkmax(ret.s11, b.s11);
    ret.s10 = max(a.s11 + b.s00, a.s10 + b.s10); checkmax(ret.s10, a.s10); checkmax(ret.s10, b.s10);
    ret.s00 = max(a.s00 + b.s10, a.s01 + b.s00); checkmax(ret.s00, a.s00); checkmax(ret.s00, b.s00);
    ret.s01 = max(a.s00 + b.s11, a.s01 + b.s01); checkmax(ret.s01, a.s01); checkmax(ret.s01, b.s01);
    return ret;
}
void pushup(int rt)
{
    sum[rt].data = sum[rt<<1].data + sum[rt<<1|1].data;
}
void build(int L, int R, int rt)
{
    sum[rt].data.init();
    if (L == R)
    {
        if (L & 1)
            sum[rt].data.s11 = d[L];
        else
            sum[rt].data.s00 = d[L];
        return;
    }
    int mid = (L + R) / 2;
    build(L, mid, rt<<1);
    build(mid + 1, R, rt<<1|1);
    pushup(rt);
}
void update(int pos, LL value, int L, int R, int rt)
{
    if (L == pos && R == pos)
    {    
        if (pos & 1)
            sum[rt].data.s11 = value;
        else
            sum[rt].data.s00 = value;
        return;
    }
    int mid = (L + R) / 2;
    if (pos <= mid)
        update(pos, value, L, mid, rt<<1);
    else
        update(pos, value, mid + 1, R, rt<<1|1);
    pushup(rt);
}
Data query(int l, int r, int L, int R, int rt)
{
    if (l <= L && r >= R)
    {
        return sum[rt].data;
    }
    int mid = (L + R) >> 1;
    Data lson, rson;
    lson.init(); rson.init();
    if (l <= mid)
        lson = query(l, r, L, mid, rt<<1);
    if (r > mid)
        rson = query(l, r, mid + 1, R, rt<<1|1);
    return lson + rson;
}
int main()
{
    int T, n, m;
    scanf("%d", &T);
    while (T--)
    {

        scanf("%d %d", &n ,&m);
        for (int i = 1; i <= n; i++)
            scanf("%I64d", &d[i]);
        build(1, n, 1);
        int op, a, b;
        for (int i = 0; i < m; i++)
        {
            scanf("%d %d %d", &op, &a, &b);
            if (op)
                update(a, (LL)b, 1, n, 1);
            else
            {
                Data ans = query(a, b, 1, n, 1);
                printf("%I64d\n", ans.max_ele());
            }
        }
    }
    return 0;
}
View Code

相关文章: