(第十四届蓝桥真题) 整数删除(线段树+二分)

news2024/11/16 21:55:42

 样例输入:

5 3
1 4 2 8 7

样例输出:

17 

分析:这道题我想的比较复杂,不过复杂度还是够用的,我是用线段树+二分来做的。

我们用线段树维护所有位置的最小值,那么我们每次删除一个数之前先求一遍最小值,不妨设最小值为mn,然后从左边开始找第一个值为mn的位置,不妨设位置为pos,我们每次删除一个数,就把这个位置设置为0x3f3f3f3f3f3f3f3f,因为可能爆int,所以设置为longlong里面的较大值。这样我们当前要删除pos位置的数,那么就把pos位置的数设置为0x3f3f3f3f3f3f3f3f,然后从pos-1向前二分寻找第一个位置i使得区间[i,pos-1]的最小值不为0x3f3f3f3f3f3f3f3f,这就是现存的左边相邻的数,同理从pos+1向后二分寻找第一个位置i使得区间[pos+1,i]的最小值不为0x3f3f3f3f3f3f3f3f,这就是现存的右边相邻的数,然后把这两个数都加上mn即可,需要注意的一点就是我们寻找位置时是在线段树内二分,要不然复杂度是n*logn*logn,这样会超时

最后我们直接把那些位置不为0x3f3f3f3f3f3f3f3f的数输出即可。

细节见代码:

#include<iostream>
#include<cmath>
#include<queue>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=2e6+10;
long long mn[N];
int l[N],r[N];
void pushup(int id)
{
	mn[id]=min(mn[id<<1],mn[id<<1|1]);
	return ;
}
void build(int id,int L,int R)
{
	l[id]=L;r[id]=R;
	if(L==R)
	{
		scanf("%lld",&mn[id]);
		return ;
	}
	int mid=L+R>>1;
	build(id<<1,L,mid);
	build(id<<1|1,mid+1,R);
	pushup(id);
}
void update_point(int id,int pos,long long x)
{
	if(l[id]==r[id])
	{
		mn[id]+=x;
		return ;
	}
	int mid=l[id]+r[id]>>1;
	if(pos<=mid) update_point(id<<1,pos,x);
	else update_point(id<<1|1,pos,x);
	pushup(id);
}
long long query_interval(int id,int L,int R)
{
	if(l[id]>=L&&r[id]<=R) return mn[id];
	int mid=l[id]+r[id]>>1;
	long long ans=0x3f3f3f3f3f3f3f3f;
	if(L<=mid) ans=min(ans,query_interval(id<<1,L,R));
	if(mid+1<=R) ans=min(ans,query_interval(id<<1|1,L,R));
	return ans;
}
int queryl_interval(int id,int L,int R,long long val)//从R-->L找第一个值小于val的位置 
{
	if(l[id]>R||r[id]<L) return 0;
	if(l[id]==r[id]&&mn[id]<val) return l[id];
	int mid=l[id]+r[id]>>1;
	int ans=0;
	if(mid+1<=R&&mn[id<<1|1]<val)
		ans=queryl_interval(id<<1|1,L,R,val);
	if(ans) return ans;
	if(L<=mid&&mn[id<<1]<val)
		ans=max(ans,queryl_interval(id<<1,L,R,val));
	return ans;
}
int queryr_interval(int id,int L,int R,long long val)//从L-->R找第一个值小于val的位置
{
	if(l[id]>R||r[id]<L) return 0x3f3f3f3f;
	if(l[id]==r[id]&&mn[id]<val) return l[id];
	int mid=l[id]+r[id]>>1;
	int ans=0x3f3f3f3f;
	if(L<=mid&&mn[id<<1]<val)
		ans=queryr_interval(id<<1,L,R,val);
	if(ans!=0x3f3f3f3f) return ans;
	if(mid+1<=R&&mn[id<<1|1]<val)
		ans=min(ans,queryr_interval(id<<1|1,L,R,val));
	return ans;
}
int main()
{
	int n,k;
	scanf("%d%d",&n,&k);
	build(1,1,n);
	while(k--)
	{
		long long mi=query_interval(1,1,n);
		int l=queryr_interval(1,1,n,mi+1);
		long long val=query_interval(1,l,l);
		update_point(1,l,0x3f3f3f3f3f3f3f3f-val);
		int t=l;
		if(t!=1)//更新左边 
		{
			int pos=queryl_interval(1,1,t-1,0x3f3f3f3f3f3f3f3f);
			if(pos)
				update_point(1,pos,val);
		}
		if(t!=n)//更新右边 
		{
			int pos=queryr_interval(1,t+1,n,0x3f3f3f3f3f3f3f3f);
			if(pos!=0x3f3f3f3f)
				update_point(1,pos,val);
		}
	}
	for(int i=1;i<=n;i++)
	{
		long long val=query_interval(1,i,i);
		if(val!=0x3f3f3f3f3f3f3f3f) printf("%lld ",val);
	}
	return 0;
}

方法二:优先队列加双向链表

我们直接用数组记录每个位置当前的真实值,然后我们用优先队列存储所有的二元组,二元组的第一维就是值,第二维是位置,因为我们不可能每次修改一个值就对应地在优先队列内进行修改,但是我们每次拿出队列首部元素时我们能够通过坐标索引找到当前位置的真实值然后与该二元组的第一维进行比较来判断当前值是否已经发生改变,如果要是值已经发生改变我们直接continue就可以,这样的话就可以使得总体复杂度降至O(nlogn)了。

细节见代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#include<vector>
#include<cmath>
using namespace std;
const int N=5e5+10;
typedef pair<long long,int> PII;
long long a[N];
int l[N],r[N],n,k;
priority_queue<PII,vector<PII>,greater<PII> >q;
void del(int pos)
{
	if(l[pos])
	{
		a[l[pos]]+=a[pos];
		r[l[pos]]=r[pos];
		q.push({a[l[pos]],l[pos]});
	}
	if(r[pos]<=n)
	{
		a[r[pos]]+=a[pos];
		l[r[pos]]=l[pos];
		q.push({a[r[pos]],r[pos]});
	}
	a[pos]=-1;
}
int main()
{
	cin>>n>>k;
	for(int i=1;i<=n;i++)
	{
		scanf("%lld",&a[i]);
		q.push({a[i],i});
		l[i]=i-1;
		r[i]=i+1;
	}
	while(k--)
	{
		PII t=q.top();
		q.pop();
		if(a[t.second]!=t.first)//该值已经无效 
		{
			k++;
			continue;
		}
		del(t.second);
	}
	for(int i=1;i<=n;i++)
		if(a[i]!=-1) printf("%lld ",a[i]);
	return 0;
}

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

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

相关文章

停车场管理系统文件录入(C++版)

❤️作者主页&#xff1a;微凉秋意 ✅作者简介&#xff1a;后端领域优质创作者&#x1f3c6;&#xff0c;CSDN内容合伙人&#x1f3c6;&#xff0c;阿里云专家博主&#x1f3c6; 文章目录一、案例需求描述1.1、汽车信息模块1.2、普通用户模块1.3、管理员用户模块二、案例分析三…

mysql:使用终端操作数据库

登录进入终端&#xff1a; mysql -u root -p 展示数据库 SHOW DATABASES; 创建数据库&#xff1a; CREATE DATABASE IF NOT EXISTS RUNOOB_TEST DEFAULT CHARSET utf8 COLLATE utf8_general_ci; 1. 如果数据库不存在则创建&#xff0c;存在则不创建。 2. 创建RUNOOB_TEST数据库…

ElasticSearch安装、启动、操作及概念简介

ElasticSearch快速入门 文件链接&#xff1a;https://pan.baidu.com/s/15kJtcHY-RAY3wzpJZIn4-w?pwd0k5a 提取码&#xff1a;0k5a 有些软件对于安装路径有一定的要求&#xff0c;例如&#xff1a;路径中不能有空格&#xff0c;不能有中文&#xff0c;不能有特殊符号&#xf…

JUC并发编程之ReentrantLock

1. 非公平锁实现原理 加锁解锁流程 构造器默认实现的是非公平锁 public ReentrantLock() {sync new NonfairSync();}NonfairSync 继承 Sync&#xff0c; Sync 继承 AbstractQueuedSynchronizer 没有竞争时 第一个竞争出现时 Thread-1 执行了 CAS 尝试将state 由 0 改为 1&…

Stable Diffusion免费(三个月)通过阿里云轻松部署服务

温馨提示&#xff1a;划重点&#xff0c;活动入口在这里喔&#xff0c;不要迷路了。 其实我就在AIGC_有没有一种可能&#xff0c;其实你早就在AIGC了&#xff1f;阿里云邀请你&#xff0c;体验一把AIGC级的毕加索、达芬奇、梵高等大师作画的快感。阿里云将提供免费云产品资源&…

如何使用evosuite为指定被测方法生成测试用例

目录 省流版本 准备工作 环境 evosuite获取 检验环境 参数解释 怎样表示被测方法 怎样指向被测类 其他参数 参考 省流版本 java -jar .\target\depd\evosuite-1.1.0.jar -generateTests -Dtarget_method"isLenient()Z" -class com.google.gson.stream.…

Midjourney教程(二)——Prompt基本结构

Midjourney教程——Prompt基本结构 Basic Prompt 基础版本的prompt仅仅包含图片的描述&#xff0c;能够满足普通的需求&#xff0c;如下图所示 Advanced Prompt 高级版本的prompt主要包含三个部分&#xff0c;如下图所示 Image Prompts(可选) prompt第一部分是Image&#x…

TCP/IP协议详解

一.引言TCP/IP 是 TCP 和 IP 两种协议群的统称&#xff0c;具体来说&#xff0c;IP 或 ICMP、TCP 或 UDP、TELNET 或 FTP、以及 HTTP 等都属于 TCP/IP 协议二.计算机网络体系结构分层计算机网络体系结构分层计算机网络体系结构分层不难看出&#xff0c;TCP/IP 与 OSI 在分层模块…

【C语言】迷宫问题

【C语言】迷宫问题一. 题目描述二. 思想2.1 算法---回溯算法2.2 思路分析图解三. 代码实现3.1 二维数组的实现3.2 上下左右四个方向的判断3.4 用栈记录坐标的实现3.5 完整代码四. 总结一. 题目描述 牛客网链接&#xff1a;https://www.nowcoder.com/questionTerminal/cf2490605…

STM32看门狗

目录 独立看门狗 IWDG 什么是看门狗&#xff1f; 独立看门狗本质 独立看门狗框图 独立看门狗时钟 分频系数算法&#xff1a; ​编辑 重装载寄存器 键寄存器 溢出时间计算公式 独立看门狗实验 需求&#xff1a; 硬件接线&#xff1a; 溢出时间计算&#xff1…

macOS设置环境变量和别名

因为我的mac所用shell是bash&#xff0c;所以本文中涉及的环境变量和别名配置均在~/.zshrc文件中,且在每次配置完成后&#xff0c;需要执行source ~/.zshrc命令使配置文件生效 环境变量 通过配置环境变量&#xff0c;我们可以将某个路径暴露到全局&#xff0c;这样可以在全局…

周总结(第一周)

3月份3个星期 *** 三个星代表不会 ** 再做 * 加强 题目1-完全二叉树(记忆) 考察数据结构 完全二叉树的深度deplog2(N1)1 完全二叉树节点的深度depiceil(log2(i1))向上舍入 完全二叉树的层次遍历&#xff0c;遍历每层的二叉树计算基础每层的总和&#xff0c;然后找出最大的和…

Talk预告 | 新加坡国立大学郑奘巍 AAAI‘23 杰出论文:大批量学习算法加速推荐系统训练

本期为TechBeat人工智能社区第486期线上Talk&#xff01; 北京时间3月30日(周四)20:00&#xff0c;新加坡国立大学二年级博士生——郑奘巍的Talk将准时在TechBeat人工智能社区开播&#xff01; 他与大家分享的主题是: “大批量学习算法加速推荐系统训练”&#xff0c;届时将分…

Kubernetes 多集群网络方案系列 2 -- Submariner 监控

Submariner 是一个用于连接 Kubernetes 集群的跨集群网络解决方案&#xff0c;可以实现集群之间的服务发现、网络通信等功能。 Prometheus 是一个开源的监控和告警系统&#xff0c;专门用于收集、存储和查询各种应用、系统和基础设施的实时指标数据。Prometheus 具备多维数据模…

Java开发 - MySQL主从复制初体验

前言 前面已经学到了很多知识&#xff0c;大部分也都是偏向于应用方面&#xff0c;在应用实战这条路上&#xff0c;博主一直觉得只有实战才是学习中最快的方式。今天带来主从复制给大家&#xff0c;在刚刚开始动手写的时候&#xff0c;才想到似乎忽略了一些重要的东西&#xf…

面试篇-揭开Spring Bean加载的神秘面纱

SpringBean加载完整过程 启动spring容器&#xff08;创建beanfactory&#xff09;->加载配置(注解、xml)->实例化bean(执行构造方法)->注入依赖->初始化bean&#xff08;设置属性值&#xff09;->使用->销毁 解析和读取 XML 配置文件或注解配置类&#xff0…

Linux嵌入式学习之Ubuntu入门(五)汇编语法学习

系列文章目录 一、Linux嵌入式学习之Ubuntu入门&#xff08;一&#xff09;基本命令、软件安装及文件结构 二、Linux嵌入式学习之Ubuntu入门&#xff08;二&#xff09;磁盘文件介绍及分区、格式化等 三、Linux嵌入式学习之Ubuntu入门&#xff08;三&#xff09;用户、用户组…

synchronized原理、偏向锁、轻量级锁、重量级锁、锁升级

文章目录Synchronized概念自增自减字节码指令临界区竞态条件基本使用原理查看synchronized的字节码指令序列Monitor对象的内存布局Mark Word是如何记录锁状态的偏向锁什么是偏向锁偏向锁延迟偏向偏向锁状态跟踪偏向锁撤销之调用对象HashCode偏向锁撤销之调用wait/notify轻量级锁…

Qt Quick - Drawer

Qt Quick - Drawer使用总结一、概述二、使用1、基础使用2、特点空间运行3、与内容转换相互挤占一、概述 Drawer提供了一个基于滑动的侧边面板&#xff0c;类似于经常在触控界面中使用的侧边面板&#xff0c;为导航提供了一个位置。 二、使用 1、基础使用 抽屉可以放置在内…

springcloud深度探索

中文官方文档&#xff1a;project - Spring Cloud Config - 《Spring Cloud中文文档》 - 书栈网 BookStackSpring Cloud ConfigFeaturesQuick StartSample Projects Spring Cloud为开发人员提供了工具&#xff0c;用以快速的在分布式系统中建立一些通用方案&#xff08;例如配…