备战蓝桥杯---线段树应用2

news2025/1/21 13:02:36

来几个不那么模板的题:

对于删除,我们只要给那个元素附上不可能的值即可,关键问题是怎么处理序号变化的问题。

事实上,当我们知道每一个区间有几个元素,我们就可以确定出它的位置,因此我们可以再维护一下前缀和即可,下面是AC代码:

#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[1000100];
struct node{
    int maxn,minn,num;
}tree[4001000];
void build(int p,int l,int r){
    if(l==r){
        tree[p].maxn=a[l];
        tree[p].minn=a[l];
        tree[p].num=1;
        return;
    }
    int mid=(l+r)/2;
    build(p*2,l,mid);
    build(p*2+1,mid+1,r);
    tree[p].maxn=max(tree[p*2].maxn,tree[p*2+1].maxn);
    tree[p].minn=min(tree[p*2].minn,tree[p*2+1].minn);
    tree[p].num=tree[p*2].num+tree[p*2+1].num;
}
void del(int p,int l,int r,int x){
    if(l==r){
        tree[p].maxn=-1e9-10;
        tree[p].minn=1e9+10;
        tree[p].num=0;
        return;
    }
    int mid=(l+r)/2;
    if(tree[p*2].num>=x) del(p*2,l,mid,x);
    else del(p*2+1,mid+1,r,x-tree[p*2].num);
    //更新
    tree[p].maxn=max(tree[p*2].maxn,tree[p*2+1].maxn);
    tree[p].minn=min(tree[p*2].minn,tree[p*2+1].minn);
    tree[p].num=tree[p*2].num+tree[p*2+1].num;
}
node query(int p,int l,int r,int x,int y){
    if(x==1&&y==tree[p].num)
    {
        return tree[p];
    }
    int mid=(l+r)/2;
    if(tree[p*2].num>=y) return query(p*2,l,mid,x,y);
    if(tree[p*2].num<x) return query(p*2+1,mid+1,r,x-tree[p*2].num,y-tree[p*2].num);
    node t1=query(p*2,l,mid,x,tree[p*2].num);
    node t2=query(p*2+1,mid+1,r,1,y-tree[2*p].num);
    t1.maxn=max(t1.maxn,t2.maxn);
    t1.minn=min(t1.minn,t2.minn);
    return t1;
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    build(1,1,n);
    for(int i=1;i<=m;i++){
        int q,x,y;
        scanf("%d",&q);
        if(q==1){
            scanf("%d",&x);
            del(1,1,n,x);//x为相对位置
        }
        else{
            scanf("%d%d",&x,&y);
            node ck=query(1,1,n,x,y);
            printf("%d %d\n",ck.minn,ck.maxn);
        }
    }
}

接题:

首先我们可以维护3,对于1,0用Lazy标识(4种)即可,对于2我们0的个数就是1的个数。

怎么求4?我们需要知道左区间末尾连续1的个数以及右区间开头连续1的个数,因为有0,那么还要维护连续0.

数10个tag(晕)。

下面是AC代码:

#include<bits/stdc++.h>
using namespace std;
int n,m;
struct node{
    int lazy;//0权变0,1全变1,2反转,-1没干
    int sum[2],max[2],left[2],right[2];
}tr[400010];
int a[100010];
void pushup(int p,int l,int r){
    int mid=(l+r)/2;
    for(int i=0;i<=1;i++){
        tr[p].sum[i]=tr[p*2].sum[i]+tr[p*2+1].sum[i];
        tr[p].max[i]=max(max(tr[p*2].max[i],tr[p*2+1].max[i]),
                        tr[p*2].right[i]+tr[p*2+1].left[i]);
        if(tr[p*2].left[i]==mid-l+1)
            tr[p].left[i]=tr[p*2].left[i]+tr[p*2+1].left[i];
        else  tr[p].left[i]=tr[p*2].left[i];
        if(tr[p*2+1].right[i]==r-mid)
            tr[p].right[i]=tr[p*2+1].right[i]+tr[p*2].right[i];
        else  tr[p].right[i]=tr[p*2+1].right[i];
        
    }
}
void build(int p,int l,int r){
    tr[p].lazy=-1;
    if(l==r){
        tr[p].sum[a[l]]=1;
        tr[p].max[a[l]]=1;
        tr[p].left[a[l]]=1;
        tr[p].right[a[l]]=1;
        return;
    }
    int mid=(l+r)/2;
    build(p*2,l,mid);
    build(p*2+1,mid+1,r);
    pushup(p,l,r);
}
void jiaohuan(int p){
        swap(tr[p].sum[0],tr[p].sum[1]);
        swap(tr[p].max[0],tr[p].max[1]);
        swap(tr[p].left[0],tr[p].left[1]);
        swap(tr[p].right[0],tr[p].right[1]);
}
void pushdown(int p,int l,int r,int mid){
    if(tr[p].lazy==2){
        jiaohuan(p*2);
        jiaohuan(p*2+1);
        if(tr[p*2].lazy==-1) tr[p*2].lazy=2;
        else if(tr[p*2].lazy==2) tr[p*2].lazy=-1;
        else tr[p*2].lazy^=1;
        if(tr[p*2+1].lazy==-1) tr[p*2+1].lazy=2;
        else if(tr[p*2+1].lazy==2) tr[p*2+1].lazy=-1;
        else tr[p*2+1].lazy^=1;
        tr[p].lazy=-1;
    }
    else{
        int a=tr[p].lazy;
        tr[2*p].lazy=a;
        tr[p*2].sum[a]=mid-l+1;
        tr[p*2].max[a]=mid-l+1;
        tr[p*2].left[a]=mid-l+1;
        tr[p*2].right[a]=mid-l+1;
        tr[p*2].sum[a^1]=0;
        tr[p*2].max[a^1]=0;
        tr[p*2].left[a^1]=0;
        tr[p*2].right[a^1]=0;
        tr[2*p+1].lazy=a;
        tr[p*2+1].sum[a]=r-mid;
        tr[p*2+1].max[a]=r-mid;
        tr[p*2+1].left[a]=r-mid;
        tr[p*2+1].right[a]=r-mid;
        tr[p*2+1].sum[a^1]=0;
        tr[p*2+1].max[a^1]=0;
        tr[p*2+1].left[a^1]=0;
        tr[p*2+1].right[a^1]=0;
        tr[p].lazy=-1;
    }
}
void change(int p,int l,int r,int x,int y,int a){
    if(x<=l&&r<=y){
        tr[p].lazy=a;
        tr[p].sum[a]=r-l+1;
        tr[p].max[a]=r-l+1;
        tr[p].left[a]=r-l+1;
        tr[p].right[a]=r-l+1;
        tr[p].sum[a^1]=0;
        tr[p].max[a^1]=0;
        tr[p].left[a^1]=0;
        tr[p].right[a^1]=0;
        return;
    }
    int mid=(l+r)/2;
    if(tr[p].lazy!=-1) pushdown(p,l,r,mid);
    if(x<=mid) change(p*2,l,mid,x,y,a);
    if(y>mid) change(p*2+1,mid+1,r,x,y,a);
    pushup(p,l,r);    
}
void rev(int p,int l,int r,int x,int y){
    if(x<=l&&r<=y){
        jiaohuan(p);
         if(tr[p].lazy==-1) tr[p].lazy=2;
        else if(tr[p].lazy==2) tr[p].lazy=-1;
        else tr[p].lazy^=1;
        return;
    }
    int mid=(l+r)/2;
    if(tr[p].lazy!=-1) pushdown(p,l,r,mid);
    if(x<=mid) rev(p*2,l,mid,x,y);
    if(y>mid) rev(p*2+1,mid+1,r,x,y);
    pushup(p,l,r); 
}
int find1(int p,int l,int r,int x,int y){
    if(x<=l&&r<=y){
        return tr[p].sum[1];
    }
    int mid=(l+r)/2;
    if(tr[p].lazy!=-1) pushdown(p,l,r,mid);
    int ans=0;
    if(x<=mid) ans+=find1(p*2,l,mid,x,y);
    if(y>mid) ans+=find1(p*2+1,mid+1,r,x,y);
    return ans;
}
node find2(int p,int l,int r,int x,int y){
    if(x<=l&&r<=y){
        return tr[p];
    }
    int mid=(l+r)/2;
    if(tr[p].lazy!=-1) pushdown(p,l,r,mid);
    if(y<=mid) return find2(p*2,l,mid,x,y);
    if(x>mid)  return find2(p*2+1,mid+1,r,x,y);
    node ans1=find2(p*2,l,mid,x,mid);
    node ans2=find2(p*2+1,mid+1,r,mid+1,y);
    ans1.max[1]=max(ans1.max[1],max(ans2.max[1],ans1.right[1]+ans2.left[1]));
    if(ans1.left[1]==mid-l+1) ans1.left[1]+=ans2.left[1];
    if(ans2.right[1]==r-mid) ans1.right[1]+=ans2.right[1];
    else ans1.right[1]=ans2.right[1];
    return ans1;
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    build(1,1,n);
    for(int i=1;i<=m;i++){
        int op,a,b;
        scanf("%d%d%d",&op,&a,&b);
        a++,b++;
        if(op==0){
            change(1,1,n,a,b,0);
        }
        if(op==1) change(1,1,n,a,b,1);
        if(op==2) rev(1,1,n,a,b);
        if(op==3)  printf("%d\n",find1(1,1,n,a,b));
        if(op==4) printf("%d\n",find2(1,1,n,a,b).max[1]);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1571536.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spark-Scala语言实战(13)

在之前的文章中&#xff0c;我们学习了如何在spark中使用键值对中的keys和values,reduceByKey,groupByKey三种方法。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢…

EdenAI

文章目录 关于 EdenAI功能说明提供的模型Eden AI PlatformIntegrations 和以下平台集成 Python 调用 API异步功能 关于 EdenAI Eden AI 用户界面&#xff08;UI&#xff09;专为处理人工智能项目而设计。 通过 Eden AI Portal&#xff0c;您可以使用市场上最好的引擎 执行无代…

深度学习方法;乳腺癌分类

乳腺癌的类型很多&#xff0c;但大多数常见的是浸润性导管癌、导管原位癌和浸润性小叶癌。浸润性导管癌(IDC)是最常见的乳腺癌类型。这些都是恶性肿瘤的亚型。大约80%的乳腺癌是浸润性导管癌(IDC)&#xff0c;它起源于乳腺的乳管。 浸润性是指癌症已经“侵袭”或扩散到周围的乳…

#SOP#-如何使用AI辅助论文创作

#SOP#-如何使用AI辅助论文创作 ——2024.4.6 “在使用工具的时候&#xff0c;要做工具的主人” 最终交付物&#xff1a; 一份可执行的AI辅助创作论文的指导手册 交付物质量要求&#xff1a; 不为任何AI大模型付费&#xff01;不为任何降重网站付费&#xff01;通过知网检查论…

视频分块上传Vue3+SpringBoot3+Minio

文章目录 一、简化演示分块上传、合并分块断点续传秒传 二、更详细的逻辑和细节问题可能存在的隐患 三、代码示例前端代码后端代码 一、简化演示 分块上传、合并分块 前端将完整的视频文件分割成多份文件块&#xff0c;依次上传到后端&#xff0c;后端将其保存到文件系统。前…

UNIAPP(小程序)每十个文章中间一个广告

三十秒刷新一次广告 ad-intervals"30" <template><view style"margin: 30rpx;"><view class"" v-for"(item,index) in 100"><!-- 广告 --><view style"margin-bottom: 20rpx;" v-if"(inde…

Kafka参数介绍

官网参数介绍:Apache KafkaApache Kafka: A Distributed Streaming Platform.https://kafka.apache.org/documentation/#configuration

深入浅出 -- 系统架构之分布式常见理论概念

随着计算机科学和互联网的发展&#xff0c;分布式场景变得越来越常见&#xff0c;能否处理好分布式场景下的问题&#xff0c;成为衡量一个工程师是否合格的标准。本文我们介绍下分布式系统相关的理论知识&#xff0c;这些理论是我们理解和处理分布式问题的基础。 CAP理论 CAP…

小林coding图解计算机网络|TCP篇06|如何理解TCP面向字节流协议、为什么UDP是面向报文的协议、如何解决TCP的粘包问题?

小林coding网站通道&#xff1a;入口 本篇文章摘抄应付面试的重点内容&#xff0c;详细内容还请移步&#xff1a;小林coding网站通道 文章目录 如何理解UDP 是面向报文的协议如何理解字节流如何解决粘包固定长度的消息 特殊字符作为边界自定义消息结构 如何理解UDP 是面向报文的…

代码随想录算法训练营第三十一天| 理论基础、LeetCode 455.分发饼干、376. 摆动序列、53. 最大子序和

一、理论基础 文章讲解&#xff1a;https://programmercarl.com/%E8%B4%AA%E5%BF%83%E7%AE%97%E6%B3%95%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html 1.贪心的定义 贪心的本质是选择每一阶段的局部最优解&#xff0c;从而达到全局最优解。例如&#xff0c;有一堆钞票&#xff0c…

使用 ChatGPT 创建在线课程:一步一步指南与提示模板

原文&#xff1a;Creating Online Courses with ChatGPT 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 谢谢 作为对你支持的感谢&#xff0c;随意定制本书中列出的任何提示&#xff0c;并将其作为你自己的重新销售。是的&#xff0c;对你免费。 它们都结构良好且用…

移动开发技术历史演化简介h5,跨平台,原生的各种技术实现方案的简单介绍

移动端的开发技术是指针对移动设备如智能手机和平板电脑等便携终端进行应用程序和服务创建的过程。本文将主要介绍一下移动端的开发技术的历史进化历程。讲述h5&#xff0c;跨平台&#xff0c;原生的各种技术实现方案和他们各自的优势与不足。 移动开发&#xff0c;不仅是编程技…

自动化测试框架Robot Framework入门

什么是RF RF是一个基于 Python 的、可扩展的关键字驱动的自动化 验收测试框架、验收测试驱动开发 &#xff08;ATDD&#xff09;、 行为驱动开发 &#xff08;BDD&#xff09; 和机器人流程自动化 &#xff08;RPA&#xff09;。它 可用于分布式、异构环境&#xff0c;其中自动…

Day82:服务攻防-开发组件安全Solr搜索Shiro身份Log4j日志本地CVE环境复现

目录 J2EE-组件Solr-本地demo&CVE 命令执行&#xff08;CVE-2019-17558&#xff09; 远程命令执行漏洞(CVE-2019-0193) Apache Solr 文件读取&SSRF (CVE-2021-27905) J2EE-组件Shiro-本地demo&CVE CVE_2016_4437 Shiro-550Shiro-721(RCE) CVE-2020-11989(身…

macU盘在电脑上读不出来 u盘mac读不出来怎么办 macu盘不能写入

对于Mac用户来说&#xff0c;使用U盘是很常见的操作&#xff0c;但有时候可能会遇到Mac电脑无法读取U盘的情况&#xff0c;这时候就需要使用一些特定的工具软件来帮助我们解决问题。本文就来告诉大家macU盘在电脑上读不出来是怎么回事&#xff0c;u盘mac读不出来怎么办。 一、m…

Java 中 Spring Boot 框架下的 Email 开发

Email 开发 1. 核心依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId> </dependency><dependency><groupId>org.springframework.boot</groupId><…

ubuntu安装sublime3并设置中文

安装Sublime Text 3 在Ubuntu上安装Sublime Text 3可以通过以下步骤进行&#xff1a; 打开终端。 导入Sublime Text 3的GPG密钥&#xff1a; wget -qO- https://download.sublimetext.com/sublimehq-pub.gpg | sudo apt-key add - 添加Sublime Text 3的存储库&#xff1a; …

Spring Boot 相关知识和工具类

写在前面 此文是对后端开发框架Spring Boot快速入门一文的知识点补充与完善&#xff0c;如果是新手小白建议两篇文章一起食用,上面那篇文章为主&#xff0c;本文为辅&#xff0c;以达到最佳效果&#xff0c;大佬随意。 http 五种与后端的交互方法 Get:主要用于请求数据。当客…

vue2+elementUi的两个el-date-picker日期组件进行联动

vue2elementUi的两个el-date-picker日期组件进行联动 <template><el-form><el-form-item label"起始日期"><el-date-picker v-model"form.startTime" change"startTimeChange" :picker-options"startTimePickerOption…

Map源码解析

基本介绍 其实HashMap底层是个什么东西我们之前也讲过, 就是一个哈希桶(差不多可以看成一个数组), 然后每一个节点又连接着链表/红黑树之类的, 下面让我们看一看具体在源码上是怎样实现的: 常量及其它 -> static final int DEFAULT_INITIAL_CAPACITY 1 << 4; //这个…