Magician(hdu 5316 线段树区间合并)

题目链接:

Magician

 

题意:

给定一个数组,定义beautiful subsequence为一个序列,里面每个元素在给定数组中的下标是奇偶交替的。

有2种操作:

0 求区间[a,b]中满足beautiful subsequence的序列中,序列所有元素之和的最大值。

1 把原数组中下标为a的那个元素的值改为b。

 

思路:

线段树单点更新+区间合并

一个区间内的beautiful subsequence只有4种情况,奇开头奇结尾、奇开头偶结尾、偶开头奇结尾和偶开头偶结尾。因此,对于每段区间,我们只要保存这4种情况的最大值,就可以根据此进行区间合并,比如奇结尾的只能跟偶开头的合并。最后,取这4种情况中的最大值即可。

 

code:

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int MAX = 100000 + 100;
const ll inf = 1e18;

typedef struct{
    ll ex[3][3];
    ll val[3][3];
}Point;

ll n,m;
Point tree[MAX<<2];

//区间合并
Point pushup(Point a,Point b)
{
    Point c;
    for(int i=0;i<2;i++){
        for(int j=0;j<2;j++){
            c.ex[i][j]=a.ex[i][j]|b.ex[i][j];
            if(a.ex[i][j]&&b.ex[i][j])
                c.val[i][j]=max(a.val[i][j],b.val[i][j]);
            else if(a.ex[i][j])
                c.val[i][j]=a.val[i][j];
            else if(b.ex[i][j])
                c.val[i][j]=b.val[i][j];
        }
    }
    for(int i=0;i<2;i++){
        for(int j=0;j<2;j++){
            for(int k=0;k<2;k++){
                if(a.ex[i][j]&&b.ex[!j][k]){
                    if(c.ex[i][k])
                        c.val[i][k]=max(c.val[i][k],a.val[i][j]+b.val[!j][k]);
                    else{
                        c.ex[i][k]=1;
                        c.val[i][k]=a.val[i][j]+b.val[!j][k];
                    }
                }
            }
        }
    }
    return c;
}

//线段树模版
void build(int l,int r,int root)
{
    memset(tree[root].ex,0,sizeof(tree[root].ex));
    if(l==r){
        ll x;
        scanf("%lld",&x);
        tree[root].ex[l%2][l%2]=1;
        tree[root].val[l%2][l%2]=x;
        return;
    }
    int mid=(l+r)>>1;
    build(l,mid,root<<1);
    build(mid+1,r,root<<1|1);
    tree[root]=pushup(tree[root<<1],tree[root<<1|1]);
}

void update(int L,ll C,int l,int r,int root)
{
    if(l==r){
        memset(tree[root].ex,0,sizeof(tree[root].ex));
        tree[root].ex[L%2][L%2]=1;
        tree[root].val[L%2][L%2]=C;
        return;
    }
    int mid=(l+r)>>1;
    if(L<=mid)  update(L,C,l,mid,root<<1);
    else update(L,C,mid+1,r,root<<1|1);
    tree[root]=pushup(tree[root<<1],tree[root<<1|1]);
    return;
}

Point query(int L,int R,int l,int r,int root)
{
    if(L<=l&&r<=R){
        return tree[root];
    }
    int mid=(l+r)>>1;
    Point ans1,ans2;
    int fg1=0,fg2=0;
    if(L<=mid){
        ans1=query(L,R,l,mid,root<<1);
        fg1=1;
    }
    if(R>mid){
        ans2=query(L,R,mid+1,r,root<<1|1);
        fg2=1;
    }
    if(fg1==0)  return ans2;
    else if(fg2==0) return ans1;
    else    return pushup(ans1,ans2);
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%lld%lld",&n,&m);
        build(1,n,1);
        while(m--){
            ll op,x,y;
            scanf("%lld%lld%lld",&op,&x,&y);
            if(op==0){
                Point ans=query(x,y,1,n,1);
                ll Max;
                int fg=0;
                //ans为4中情况的最大值
                for(int i=0;i<2;i++){
                    for(int j=0;j<2;j++){
                        if(ans.ex[i][j]){
                            if(fg==0){
                                Max=ans.val[i][j];
                                fg=1;
                            }
                            else
                                Max=max(Max,ans.val[i][j]);
                        }
                    }
                }
                printf("%lld\n",Max);
            }
            else if(op==1){
                update(x,y,1,n,1);
            }
        }
    }
    return 0;
}

 

### 回答1: magician_robot.zip 是一个压缩文件,其具体内容和用途需要依据实际情况而定。一般来说,这个压缩文件可能包含有关魔术师机器人的源代码、二进制编译文件、文档/说明文件等。魔术师机器人是一种可以模仿人类魔术师对物体的控制和掌控能力,自动完成一些魔术表演的机器人系统。通过这个系统,人们可以实现更为复杂和精密的魔术表演,同时为智能机器人领域的发展带来了新的思路和技术。如果要使用 magican_robot.zip,需先解压缩文件,然后根据具体说明,安装相应软件或直接运行相应程序,即可实现机器人的魔术表演。 ### 回答2: magician_robot.zip是一个文件压缩包,其中可能包含有关于魔术师机器人的信息或者程序代码。魔术师机器人是一种特殊的机器人,可以模拟魔术师的表演,展示一些令人惊叹的魔术表演。它通常有人形外观,配备了触觉传感器、摄像头等多个传感器设备,可以对周围环境进行感知,并且配备了多个舵机和电动机,可以完成复杂的动作,如抓取物体、做手势、发声等。魔术师机器人的设计和制造需要涉及机械、电子、计算机等多个学科领域的知识,是相当高级复杂的智能机器人系统。如果您想研究制造魔术师机器人或者了解相关信息,可能需要下载并解压缩magician_robot.zip文件,从其中获得更多有关该机器人的信息。 ### 回答3: magician_robot.zip是一个文件夹,其名称中的“magician”表示魔术师,而“robot”表示机器人。因此,magician_robot.zip可能是一个用于魔术表演的机器人程序或设计文件。 在现今数字化的时代,机器人技术得到了快速发展并广泛应用。一些魔术师也开始使用机器人来加强他们的表演效果。由于机器人的动作可以被精确地编程和控制,因此可以创造出更加惊险刺激的魔术效果。 因此,magician_robot.zip可能包含了一个用于机器人表演的程序或设计文件,其中可能包含了机器人运动路径、音效和灯光控制等内容。如果您有机器人和魔术的兴趣,您可以打开这个文件夹,深入探索其中的内容并利用它们来展示您的魔术技能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值