您的位置:首页 > 大数据 > 人工智能

HDU 5316 Magician 2015 Multi-University Training Contest 3 1001 线段树

2015-07-29 15:11 471 查看
这道题的意思是,给你一个序列,查询一段区间l,r之间奇偶交错的子序列中最大的和,在这道题目中,我们需要维护四个数组,分别是奇开头奇结尾,奇开头偶结尾,偶开头偶结尾,偶开头奇结尾四个数组。在维护的时候注意奇偶相间就好了,比方说一个父节点,他有两个儿子,如果要维护他的奇奇数组,只需要找左儿子的奇偶数组,右儿子的奇奇数组,左儿子的奇奇数组和右儿子的偶奇数组,取大的那个,再与左儿子的奇奇数组,右儿子的奇奇数组比大小,最后最大的那个就是此节点的奇奇数组。
#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#define maxn 100000#define mem(a, b) memset(a, b, sizeof(a))#pragma comment(linker, "/STACK:102400000,102400000");using  namespace std;const __int64 inf = 1e18 + 7;int nn, m;__int64 jj[maxn * 4 + 5], jo[maxn * 4 + 5], oo[maxn * 4 + 5], oj[maxn * 4 + 5];struct node{    __int64 oo, oj, jo, jj;};void build(int l, int r, int n){    if(l == r)    {        if(l % 2)        {            scanf("%I64d", &jj);            jo = oo = oj = -inf;        }        else        {            scanf("%I64d", &oo);            jo = jj = oj = -inf;        }        return;    }    int mid = (l + r) / 2;    build(l, mid, n * 2);    build(mid + 1, r, n * 2 + 1);    jj = max(max(max(jo[n * 2] + jj[n * 2 + 1], jj[n * 2] + oj[n * 2 + 1]), jj[n * 2]), jj[n * 2 + 1]);    jo = max(max(max(jj[n * 2] + oo[n * 2 + 1], jo[n * 2] + jo[n * 2 + 1]), jo[n * 2]), jo[n * 2 + 1]);    oo = max(max(max(oo[n * 2] + jo[n * 2 + 1], oj[n * 2] + oo[n * 2 + 1]), oo[n * 2]), oo[n * 2 + 1]);    oj = max(max(max(oo[n * 2] + jj[n * 2 + 1], oj[n * 2] + oj[n * 2 + 1]), oj[n * 2]), oj[n * 2 + 1]);}void change(int l, int r, int n, int ll, __int64 v){    if(l == r&&l == ll)    {        if(l % 2)        {            jj = v;            jo = oo = oj = -inf;        }        else        {            oo = v;            jo = jj = oj = -inf;        }        return;    }    if(l > ll||r < ll)        return;    int mid = (l + r) / 2;    change(l, mid, n * 2, ll, v);    change(mid + 1, r, n * 2 + 1, ll, v);    jj = max(max(max(jo[n * 2] + jj[n * 2 + 1], jj[n * 2] + oj[n * 2 + 1]), jj[n * 2]), jj[n * 2 + 1]);    jo = max(max(max(jj[n * 2] + oo[n * 2 + 1], jo[n * 2] + jo[n * 2 + 1]), jo[n * 2]), jo[n * 2 + 1]);    oo = max(max(max(oo[n * 2] + jo[n * 2 + 1], oj[n * 2] + oo[n * 2 + 1]), oo[n * 2]), oo[n * 2 + 1]);    oj = max(max(max(oo[n * 2] + jj[n * 2 + 1], oj[n * 2] + oj[n * 2 + 1]), oj[n * 2]), oj[n * 2 + 1]);}struct node que(int l, int r, int n, int ll, int rr){    if(l == ll&&r == rr)    {        struct node tmp;        tmp.jj = jj;        tmp.jo = jo;        tmp.oj = oj;        tmp.oo = oo;        return tmp;    }    int mid = (l + r) / 2;    if(rr <= mid)        return que(l, mid, n * 2, ll, rr);    else if(ll > mid)        return que(mid + 1, r, n * 2 + 1, ll, rr);    else    {        struct node tmp, tmp1, tmp2;        tmp1 = que(l, mid, n * 2, ll, mid);        tmp2 = que(mid + 1, r, n * 2 + 1, mid + 1, rr);        tmp.oo = max(max(max(tmp1.oo + tmp2.jo, tmp1.oj + tmp2.oo), tmp1.oo), tmp2.oo);        tmp.oj = max(max(max(tmp1.oo + tmp2.jj, tmp1.oj + tmp2.oj), tmp1.oj), tmp2.oj);        tmp.jo = max(max(max(tmp1.jo + tmp2.jo, tmp1.jj + tmp2.oo), tmp1.jo), tmp2.jo);        tmp.jj = max(max(max(tmp1.jo + tmp2.jj, tmp1.jj + tmp2.oj), tmp1.jj), tmp2.jj);        return tmp;    }}int main(){    int cas, a, b;    scanf("%d", &cas);    while(cas--)    {        scanf("%d%d", &nn, &m);        build(1, nn, 1);        for(int i = 0;i < m;i++)        {            scanf("%d%d", &a, &b);            if(!a)            {                int c;                scanf("%d", &c);                if(b > c)                    swap(b, c);                struct node tmp = que(1, nn, 1, b, c);                __int64 ans = max(max(max(tmp.jj, tmp.jo), tmp.oj), tmp.oo);                printf("%I64d\n", ans);            }            else            {                __int64 c;                scanf("%I64d", &c);                change(1, nn, 1, b, c);            }        }    }    return 0;}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: