zoukankan      html  css  js  c++  java
  • hdu 5316 Magician 线段树维护最大值

    题目链接:Magician

    题意:

    给你一个长度为n的序列v,你需要对这个序列进行m次操作,操作一共有两种,输入格式为

    type a b

    1、如果type==0,你就需要输出[a,b]区间内的美丽序列中所有元素的和,要使得这个值尽可能大

    2、如果type==1,你就需要把a位置的元素值改为b

    区间[a,b]的美丽序列就是va,va+1...vb。你需要从中取出任意个元素,这些元素的位置必须是奇偶交替

    例如给你一个序列1,2,3,4,5,6,7

    你取出来的美丽序列就有可能使1,2,3,4,5,6,7或者1,4,5,6,7或者2,5,6,7

    题解:

    我们使用线段树,如果type==1的时候就修改就可以了。对于type==0的情况。我们可以维护四个值,分别是区间[a,b]内的美丽序列:

    从一个偶数位置开始,到一个奇数位置截至,我们使用ab来代替

    从一个奇数位置开始,到一个奇数位置截至,我们使用bb来代替

    从一个偶数位置开始,到一个偶数位置截至,我们使用aa来代替

    从一个奇数位置开始,到一个偶数位置截至,我们使用ba来代替

    对于线段树上一个节点维护的值,我们把这个节点称为a,把它的左右节点称为b,c

    a.ab=max(b.aa+c.bb,b.ab+c.ab);   如果左右子树合并
    a.ab=max(a.ab,max(b.ab,c.ab));   如果左右子树不合并

     

    其他四个值的维护也是这样

    代码:

    #include <map>
    #include <set>
    #include <list>
    #include <queue>
    #include <deque>
    #include <cmath>
    #include <stack>
    #include <vector>
    #include <bitset>
    #include <cstdio>
    #include <string>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int maxn = 1e5+10;
    const int INF = 0x3f3f3f3f;
    const double PI = 3.1415926;
    const long long N = 1000006;
    const double eps = 1e-10;
    typedef long long ll;
    #define qmh(x) ask()
    #define mt(A, B) memset(A, B, sizeof(A))
    #define lson L, mid, rt<<1
    #define rson mid + 1, R, rt<<1|1
    #define ls rt<<1
    #define rs rt<<1|1
    #define SIS std::ios::sync_with_stdiget_mod_new(z-x)o(false), cin.tie(0), cout.tie(0)
    #define pll pair<long long, long long>
    #define lowbit(abcd) (abcd & (-abcd))
    #define max(a, b) ((a > b) ? (a) : (b))
    #define min(a, b) ((a < b) ? (a) : (b))
    struct node
    {
        ll aa,bb,ab,ba;
        void Clear()
        {
            aa=bb=ab=ba=-INF;
        }
    } tree[400009],result;
    int arr[100009];
    
    void Merge(node &a,node b,node c)
    {
        a.aa=max(b.ab+c.aa,b.aa+c.ba);
        a.aa=max(a.aa,max(b.aa,c.aa));
        a.bb=max(b.ba+c.bb,b.bb+c.ab);
        a.bb=max(a.bb,max(b.bb,c.bb));
        a.ab=max(b.aa+c.bb,b.ab+c.ab);
        a.ab=max(a.ab,max(b.ab,c.ab));
        a.ba=max(b.bb+c.aa,b.ba+c.ba);
        a.ba=max(a.ba,max(b.ba,c.ba));
    }
    
    void build(int rt,int L,int R)
    {
        if(L==R)
        {
            tree[rt].Clear();
            if(L&1) tree[rt].aa=arr[L];
            else tree[rt].bb=arr[L];
            return ;
        }
        int mid=(L+R)>>1;
        build(rt<<1,L,mid),build(rt<<1|1,mid+1,R);
        Merge(tree[rt],tree[rt<<1],tree[rt<<1|1]);
    }
    
    void update(int rt,int L,int R,int pos,int val)
    {
        if(L==R)
        {
            tree[rt].Clear();
            if(L&1) tree[rt].aa=val;
            else tree[rt].bb=val;
            return ;
        }
        int mid=(L+R)>>1;
        if(pos<=mid) update(rt<<1,L,mid,pos,val);
        else update(rt<<1|1,mid+1,R,pos,val);
        Merge(tree[rt],tree[rt<<1],tree[rt<<1|1]);
    }
    
    void query(int rt,int L,int R,int LL,int RR)
    {
        if(L>=LL&&R<=RR)
        {
            Merge(result,result,tree[rt]);
            return ;
        }
        int mid=(L+R)>>1;
        if(mid>=LL) query(rt<<1,L,mid,LL,RR);
        if(RR>mid) query(rt<<1|1,mid+1,R,LL,RR);
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int n,m;
            scanf("%d%d",&n,&m);
            for(int i=1; i<=n; i++) scanf("%d",&arr[i]);
            build(1,1,n);
            while(m--)
            {
                int type,l,r;
                scanf("%d%d%d",&type,&l,&r);
                if(type==1) update(1,1,n,l,r);
                else
                {
                    result.Clear();
                    query(1,1,n,l,r);
                    printf("%lld
    ",max(max(result.aa,result.bb),max(result.ab,result.ba)));
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    except与besides
    think用法
    walk用法
    complain用法
    go through用法
    herd用法
    ridiculous用法
    it is the same as用法
    let us say用法
    1002 A+B for Polynomials (25 分)(模拟)
  • 原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/13704788.html
Copyright © 2011-2022 走看看