【位运算 拆位法 二分】3007. 价值和小于等于 K 的最大数字

news2024/9/23 19:14:21

本文涉及知识点

位运算 拆位法
二分查找算法合集

LeetCode3007. 价值和小于等于 K 的最大数字

给你一个整数 k 和一个整数 x 。整数 num 的价值是由它的二进制表示中,从最低有效位开始,x,2x,3x,以此类推,这些位置上 设置位 的数目来计算。下面的表格包含了如何计算价值的例子。
x num Binary Representation Price
1 13 000001101 3
2 13 000001101 1
2 233 011101001 3
3 13 000001101 1
3 362 101101010 2

num 的 累加价值 是从 1 到 num 的数字的 总 价值。如果 num 的累加价值小于或等于 k 则被认为是 廉价 的。
请你返回 最大 的廉价数字。

示例 1:

输入:k = 9, x = 1
输出:6
解释:由下表所示,6 是最大的廉价数字。
x num Binary Representation Price Accumulated Price
1 1 001 1 1
1 2 010 1 2
1 3 011 2 4
1 4 100 1 5
1 5 101 2 7
1 6 110 2 9
1 7 111 3 12
示例 2:

输入:k = 7, x = 2
输出:9
解释:由下表所示,9 是最大的廉价数字。
x num Binary Representation Price Accumulated Price
2 1 0001 0 0
2 2 0010 1 1
2 3 0011 1 2
2 4 0100 0 2
2 5 0101 0 2
2 6 0110 1 3
2 7 0111 1 4
2 8 1000 1 5
2 9 1001 1 6
2 10 1010 2 8

提示:

1 <= k <= 1015
1 <= x <= 8

二分

由于价值是自然数,所有随着mid增加而增加或不变,这就有了单调性。
count函数返回mid的积分和,count(mid) <= k符合条件,有多个取最后一个。故用左闭右开空间。
count函数:
枚举x-1,2x-1 ⋯ \cdots 各为1的数量,long long 出度符合位 ,63 位,我们权枚举。 可以少枚举几位,性能稍微提升。
<= mid的数中 有多少个数 第y为1:

0到mid共mid+1个数:
第0位: 010101 交替
第1为:00110011 交替
第2位:00001111
一个周期的数量:const long long iUnit = 1LL << (i+1); i为62是会越界,可以用半周期。
z个完整的周期数有一半的数字是1,余下不完整的周期 z1 = (mid+1)%iUnit - iUnit /2
z1 = max(0,z1)
二分的上界为什么是: k*2+10000
x最大是8,故一个完整周期最大是28,远远小于10000。
2k个数加上10000后,至少有2k个数在完整周期内,也就是至少k个数符合要求。

代码

namespace NBinarySearch
{
	template<class INDEX_TYPE, class _Pr>
	INDEX_TYPE FindFrist(INDEX_TYPE left, INDEX_TYPE rightInclue, _Pr pr)
	{
		while (rightInclue - left > 1)
		{
			const auto mid = left + (rightInclue - left) / 2;
			if (pr(mid))
			{
				rightInclue = mid;
			}
			else
			{
				left = mid;
			}
		}
		return rightInclue;
	}

	template<class INDEX_TYPE, class _Pr>
	INDEX_TYPE FindEnd(INDEX_TYPE leftInclude, INDEX_TYPE right, _Pr pr)
	{
		while (right - leftInclude > 1)
		{
			const auto mid = leftInclude + (right - leftInclude) / 2;
			if (pr(mid))
			{
				leftInclude = mid;
			}
			else
			{
				right = mid;
			}
		}
		return leftInclude;
	}
}

class Solution {
public:
	long long findMaximumNumber(long long k, int x) {
		auto Can = [&](long long mid) {
			const auto numCnt = mid + 1;
			long long llCnt = 0;
			for (int i = x - 1; i < 62; i += x) {
				const long long iUnit = 1LL << (i+1);
				const long long iHalfUnit = iUnit / 2;
				llCnt += numCnt / iUnit * iHalfUnit;
				llCnt += max(0LL, numCnt % iUnit - iHalfUnit);
			}
			return llCnt <= k;
		};
		return NBinarySearch::FindEnd(0LL,
		, Can);

	}
};

使用半周期

namespace NBinarySearch
{
	template<class INDEX_TYPE, class _Pr>
	INDEX_TYPE FindFrist(INDEX_TYPE left, INDEX_TYPE rightInclue, _Pr pr)
	{
		while (rightInclue - left > 1)
		{
			const auto mid = left + (rightInclue - left) / 2;
			if (pr(mid))
			{
				rightInclue = mid;
			}
			else
			{
				left = mid;
			}
		}
		return rightInclue;
	}

	template<class INDEX_TYPE, class _Pr>
	INDEX_TYPE FindEnd(INDEX_TYPE leftInclude, INDEX_TYPE right, _Pr pr)
	{
		while (right - leftInclude > 1)
		{
			const auto mid = leftInclude + (right - leftInclude) / 2;
			if (pr(mid))
			{
				leftInclude = mid;
			}
			else
			{
				right = mid;
			}
		}
		return leftInclude;
	}
}

class Solution {
public:
	long long findMaximumNumber(long long k, int x) {
		auto Can = [&](long long mid) {
			const auto numCnt = mid + 1;
			long long llCnt = 0;
			for (int i = x - 1; i < 63; i += x) {
				const long long iHalfUnit = 1LL << i ;
				long long iUnitCnt = numCnt / iHalfUnit / 2;
				llCnt += iUnitCnt * iHalfUnit;
				llCnt += max(0LL, numCnt - iUnitCnt* iHalfUnit*2 - iHalfUnit);
			}
			return llCnt <= k;
		};
		return NBinarySearch::FindEnd(0LL, 2*k+ 10000, Can);
	}
};

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

相关下载

想高屋建瓴的学习算法,请下载《喜缺全书算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想对大家说的话
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

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

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

相关文章

Ansible在macOS上的安装部署

一、安装 Ansible&#xff08;使用 Homebrew&#xff09; 安装 Homebrew&#xff08;如果尚未安装&#xff09;&#xff1a; /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"使用 Homebrew 安装 Ansible&#x…

OWASP发布大语言模型网络安全与治理清单

当前人工智能技术面临的最大风险是大语言模型&#xff08;LLM&#xff09;和生成式人工智能技术的发展和应用速度已经远远超过了安全和治理的速度。 OpenAI、Anthropic、谷歌和微软等公司的生成式人工智能和大语言模型产品的使用正呈指数级增长。与此同时&#xff0c;开源大语…

Docker 部署 MongoDB 数据库

文章目录 官网地址docker 网络mongod.conf部署 MongoDB部署 mongo-expressdocker-compose.ymlMongoDB shell 官网地址 https://www.mongodb.com/zh-cn docker 网络 # 创建 mongo_network 网络 docker network create mongo_network # 查看网络 docker network list # 容器连…

基于Springboot的简历系统

基于SpringbootVue的简历系统的设计与实现 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringbootMybatis工具&#xff1a;IDEA、Maven、Navicat 系统展示 用户登录 首页 简历模板 招聘会 求职论坛 系统公告 后台登录 后台首页 用户管理 简历模板 模板…

Ubuntu24.04之软件源修改

注意事项 Ubuntu24.04的软件源从/etc/apt/sources.list改为/etc/apt/sources.list.d/ubuntu.sources 修改步骤 #备份软件源 sudo cp /etc/apt/sources.list.d/ubuntu.sources /etc/apt/sources.list.d/ubuntu.sources.bak #更换软件源&#xff08;更换为中科大源&#xff0…

Flask + Bootstrap vs Flask + React/Vue:初学者指南

在这篇博客文章中&#xff0c;我们将比较 Flask Bootstrap 和 Flask React/Vue 这两种技术栈&#xff0c;以帮助初学者了解哪种组合更适合他们的项目需求。我们将从学习曲线、易用性、依赖管理、构建部署和路由定义等方面进行比较。 学习曲线 Flask 是一个基于 Python 的轻…

RIP最短路实验(华为)

思科设备参考&#xff1a;RIP最短路实验&#xff08;思科&#xff09; 一&#xff0c;技术简介 RIP&#xff08;Routing Information Protocol&#xff0c;路由信息协议&#xff09;是一种基于距离矢量的内部网关协议&#xff0c;工作原理是每个路由器周期性地向邻居路由器发…

阿里云服务器上配置Docker 以及常用命令讲解

目录 一、认识docer二、在阿里云服务器上配置Docker三、底层原理4、常用命令&#xff08;1&#xff09;Docker中常见镜像命令&#xff08;2&#xff09;Docker中常见容器命令&#xff08;3&#xff09;日志查看命令&#xff08;4&#xff09;进入容器的命令与拷贝命令 一、认识…

个人博客建设必备:精选域名和主机的终极攻略

本文目录 &#x1f30f;引言&#x1f30f;域名的选择&#x1f315;域名的重要性品牌识别营销和宣传可访问性和易记性信任和权威感搜索引擎优化&#xff08;SEO&#xff09;未来的灵活性和扩展性保护品牌 &#x1f315;如何选择域名&#x1f315;工具与资源分享国内的主流域名注…

Idea修改【Help->Edit Custom VM Options...】后,导致idea无法正常启动的解决方法

一、错误场景: 二、解决方法&#xff1a; 修改文件路径&#xff1a;C:\Users\tianjm&#xff08;写自己的用户名&#xff09;\AppData\Roaming\JetBrains\IdeaIC2024.1&#xff08;选自己安装的版本&#xff09;

OpenHarmony多媒体-ijkplayer

简介 ijkplayer是OpenHarmony环境下可用的一款基于FFmpeg的视频播放器。 演示 编译运行 1、通过IDE工具下载依赖SDK&#xff0c;Tools->SDK Manager->OpenHarmony SDK 把native选项勾上下载&#xff0c;API版本>9 2、开发板选择RK3568&#xff0c;ROM下载地址. 选择…

jvm中提前进入老年代

在JVM中&#xff0c;对象的“年龄”通常指的是对象经过了多少次Minor GC&#xff08;新生代垃圾回收&#xff09;后仍然存活。每次Minor GC后&#xff0c;存活的对象会被移动到Survivor区&#xff0c;并且它们的年龄会增加。当对象的年龄达到某个阈值&#xff08;这个阈值可以通…

java锁介绍

乐观锁 乐观地认为并发访问不会造成数据冲突&#xff0c;只在更新时检查是否有冲突。乐观锁和CAS的关系可以用“乐观锁是一种思想&#xff0c;CAS是一种具体的实现”来理解。 当使用CAS操作修改数据时&#xff0c;如果版本号不匹配或者其他线程已经修改了要操作的数据&#x…

AI讲师人工智能讲师大模型培训讲师叶梓:突破大型语言模型推理效率的创新方法

大型语言模型&#xff08;LLM&#xff09;在自然语言处理&#xff08;NLP&#xff09;任务中展现出了前所未有的能力&#xff0c;但它们对计算资源的巨大需求限制了其在资源受限环境中的应用。SparQ Attention算法提出了一种创新的方法&#xff0c;通过减少注意力机制中的内存带…

混合app开发

安卓与h5交互 原生调用js js调用原生 ios与h5交互 代码演示 ios调用h5 xcode创建一个ios项目 h5调用原生 h5部分代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" conten…

二分法问题

日升时奋斗&#xff0c;日落时自省 目录 1、二分法 2、二分法问题 2.1 、在排序数组中查找元素的第一个和最后一个位置 2.2、搜索插入位置 2.3、山脉数组的峰顶索引 2.4、0-n-1中缺失的数字 1、二分法 二分法是比较简单的一种查找算法&#xff0c;但是效率很高&#xff0…

掌握Node Version Manager(nvm):跨平台Node.js版本管理

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

瀑布流组件(vue2)

文档连接&#xff1a;clz 加载状态、行数 可以自行控制&#xff0c;目前只支持vue2 实现效果&#xff1a;

【TDSQL】TCPMSS最大数据分段大小值不合理导致JAVA程序连接数据库异常案例

欢迎关注“数据库运维之道”公众号&#xff0c;一起学习数据库技术! TDSQL核心架构原理解析下载链接&#xff1a;百度网盘 请输入提取码 提取码&#xff1a;vat5 DTC2024 数据技术嘉年华&#xff08;演讲资料下载&#xff09;DTC2024 数据技术嘉年华&#xff08;演讲资料下载…

生成人工智能体:人类行为的交互式模拟论文与源码架构解析(5)——可控评估端到端评估

最后完结篇,文末有测试中发现的有趣现象,并附上了相关资料链接~ 5.可控评估 分两个阶段评估生成代理。我们从一个更加严格控制的评估开始,单独评估代理的响应,以了解它们是否在狭义上定义的上下文中产生可信的行为。然后,在我们对代理社区进行为期两天的端到端分析中,我…