位运算、状态压缩、枚举子集汇总

本文涉及知识点

证明容斥原理和证明集合枚举都用到了:二项式定理
【数学归纳法 组合数学】容斥原理

基础知识

位运算优先级

位运算的结合性都是从左到右。优先级低的先运算。

优先级位运算符说明
7<< >>位左移/位右移
10&按位与
11^按位异或
12按位或

注意:不同的编译系统的实现可能不同,所以加上括号保险。就算你把运算顺序牢记于心,你的同事未必记得。

异或(xor ^ )

定义:x1 ⊕ \oplus x2 = y,对各二进制位分别运算,如果x1和x2的某个二进制位不同(异),则y的此二进制位为1,否则为0。
性质一:
n个数的异或和(积),如果这n个数的某个二进制为1的数量是偶数,则结果的此二进制位是0(偶数个1);否则结果的此二进制为是1(奇数个1)。现在用数学归纳发证明:
a, {1,1}和{0,0}是偶数个1,结果为0;{1,0},{0,1} 奇数个1,结果为1。
b,假设n个数符合,则n+1个数也符合。将前两个数进行异或运算就符合假设了。
推论一:
根据性质一,可得如下推论:n个数求异或积,可以任意调换数的顺序结果不变。
性质二:
0 ⊕ \oplus x = x
性质三:
x ⊕ \oplus x = 0
性质四,异或逆运算是其本身:
x1 ⊕ \oplus x2 = y ,则 y ⊕ \oplus x2 = x1
性质五:
x1 ⊕ \oplus x2 <= x1 + x2
如果x1,x2的 所有的二进制位不同时为1,则 x1 ⊕ \oplus x2 == x1 + x2
否则: x1 ⊕ \oplus x2 < x1 + x2

习题

n双m种筷子, 遗失一只,求遗失的一只长度。m值未知。
已知:2n-1只筷子的长度:{a1,a2 ⋯ a 2 n − 2 , a 2 n − 1 \cdots a_{2n-2},a_{2n-1} a2n2,a2n1 }
思路:根据性质三,答案就是这2n-1的数的异或积。

位与(&)

定义: x1 & \And & x2 = y。对二进制位分别运算,x1和x2的某二进制位全部为1,y对应的二进制位为1;否则为0。
性质一:
n个数依次位与结果为y,如果这n个数的某二进制位全部为1,则y的对应二进制位为1,否则为0。
推论一:
根据性质一,可得如下推论:n个数求与积,可以任意调换数的顺序结果不变。
性质二:
(-1)&x = x
性质三:
x1 & \And & x2 = y <=min(x1,x2)

位或(|)

定义: x1 ∨ \lor x2 = y。对二进制位分别运算,x1和x2的某二进制位全部为0,y对应的二进制位为0;否则为1。
性质一:
n个数依次位与结果为y,如果这n个数的某二进制位全部为0,则y的对应二进制位为0,否则为1。
推论一:
根据性质一,可得如下推论:n个数求与积,可以任意调换数的顺序结果不变。
性质二:
0 ∨ \lor x = x
性质三:
x1 ∨ \lor x2 >= max(x1,x2)

取反(~)

定义:各二进制位0变1,1变0。

位左移(<<)、位右移(>>)

x << n ,相当于x × \times × 2n
x >> n, 相当于 x ÷ \div ÷ 2n

状态压缩

用int mask的二进制位代替一个bool数组v,此数组长度不超过31。第i位为1,表示v[i]=true;第i位为0,表示v[i]=false。
mask&(1<<i) 表示mask第i为1。i ∈ \in [0,31) 最低位i是0。以下操作,只影响第i位,不影响其它位。
如果mask第i位无论是0还是1,设置为1 mask |=(1<<i)
如果mask第i位是无论是1还是0,设置为0 mask &=~(1<<i)
将mask的第一位取反(0变1,1变0)。 mask ^=(1 << i)

子集状态压缩(枚举子集)

从大到小枚举mask的子集,寻找下一个子集,如果sub为0,没有比它小的子集。否则从右到左寻找第一个不为0的位,假定此位是i1,将i1位减1,也就是变成0。i1后面的位取最大,也就是mask的后i1位。
sub-1 :由于是从大到小枚举,所以(sub-1)比i1高的位和mask一致。
第i1位变成0。
比i1位低的全为1。
故:mask&(sub-1)就是 比sub小的最大子集。
注意:通过此方法枚举maxMask =(1<<n)-1所有子集的子集的时间复杂度是O(3n)。下面利用二项式定理。
0被maxMask 所有子集枚举,共2n次。
有且仅有一个二进位为1的数共有 ( n 1 ) n \choose 1 (1n)个,被2n-1个子集枚举。除当前位必须是1,其它位01皆可。
有且仅有2个二进位为1的数共有 ( n 2 ) n \choose 2 (2n)个,被2n-2个子集枚举。
∑ i : 0 n ( n i ) 1 i 2 n − i = ( 1 + 2 ) n = 3 n 根据二项式定理 \sum_{i:0}^n{n \choose i}1^i2^{n-i}\\ =(1+2)^n = 3^n \quad 根据二项式定理 i:0n(in)1i2ni=(1+2)n=3n根据二项式定理

常见的运算

x是正整数
(x-1) & \And & x :将最低位的1设置成0。
令第i1位是1,如果有多位是1,i1是最小的。

比i1高的位i1位比第i1第的位
x-1和x相同0全为1
x不变1全为0

比i1高的位:两者完全相同,故不变。
i1位:一个为1,一个为1,故为0。
比i1低的为:一个为1,一个为0,故全为0。

(-x) & \And &x
除最低位的1外,全部置成0。
负数存储的是补码,反码+1.
令第i1位是1,如果有多位是1,i1是最小的。

比i1高的位i1位比第i1第的位
-x的反码和x相反0全为1
-x的补码和x相反1全为0
x的原码不变1全为0

比i1高的位: x和-x相反,故全为0。
i1位:x和-x都为1,故结果为1。
比i1低的位: x和-x都为0,故结果为0。

区间(子数组)位与(位或)模板

vector<int> nums;

t r = & x = l r n u m s [ x ] t_r= \Large\And_{x=l}^r nums[x] tr=&x=lrnums[x]
集合s 记录所有的tr,则s的元素数量,最大31个。因为删除重复元素后,tr的二进制1至少少1个。

位或类似,每个不重复的元素至少增加一个1。
最大公约数,也是如此。每次至少除以2。

vector<vector<pair<int, int>>> vNumIndex(nums.size());
for (int i = 0; i < nums.size(); i++) {
	if (i) {
		for (const auto& [preNum, preIndex] : vNumIndex[i - 1]) {
			const int iNew = preNum | nums[i];
			if (vNumIndex[i].empty() || (vNumIndex[i].back().first != iNew)) {
				vNumIndex[i].emplace_back(make_pair(iNew, preIndex));
			}
			else {
				vNumIndex[i].back().second = preIndex;
			}
		}
	}
	if (vNumIndex[i].empty() || (vNumIndex[i].back().first != nums[i])) {
		vNumIndex[i].emplace_back(make_pair(nums[i], i));
	}
	else {
		vNumIndex[i].back().second = i;
	}
}

vNumIndex[i]记录 nums[x…i]的异或值(不重复)及索引。重复值保留索引大的。x ∈ \in [0,x]。

第二个版本的模版

class CRangCal {
public:
	template<class _Pr, class T = int>
	static vector<vector<pair<T, int>>> RangCal(const vector<T>& nums, _Pr pr) {
		vector<vector<pair<int, int>>> vNumIndex(nums.size());
		for (int i = 0; i < nums.size(); i++) {
			if (i) {
				for (const auto& [preNum, preIndex] : vNumIndex[i - 1]) {
					auto iNew = pr(preNum, nums[i]);
					if (vNumIndex[i].empty() || (vNumIndex[i].back().first != iNew)) {
						vNumIndex[i].emplace_back(make_pair(iNew, preIndex));
					}
					else {
						vNumIndex[i].back().second = preIndex;
					}
				}
			}
			if (vNumIndex[i].empty() || (vNumIndex[i].back().first != nums[i])) {
				vNumIndex[i].emplace_back(make_pair(nums[i], i));
			}
			else {
				vNumIndex[i].back().second = i;
			}
		}
		return vNumIndex;
	}
};

例题

模板题

【位运算】3097. 或值至少为 K 的最短子数组 II
【动态规划 区间dp 位运算】3117. 划分数组得到最小的值之和
【线段树 区间位运算模板】3117划分数组得到最小的值之和

拆位法

【位运算 拆位法 二分】3007. 价值和小于等于 K 的最大数字
【位运算 拆位法】1835. 所有数对按位与结果的异或和

试填法

【位运算 试填法】【推荐】3022. 给定操作次数内使剩余元素的或值最小
【位运算 反证法 试填法】2897.对数组执行操作使平方和最大

子集状态压缩(枚举子集)

【位运算 子集状态压缩】982按位与为零的三元组
【位运算 状态压缩 枚举子集】1178. 猜字谜
【动态规划】【子集状态压缩】LCP04 覆盖

其它

【位运算】【二分查找】【C++算法】3007价值和小于等于 K 的最大数字
【深度优化(DFS) 记忆化 位运算】:2920收集所有金币可获得的最大积分
【二分查找】【位运算】2354.优质数对的数目
【数论】【分类讨论】【位运算】1611使整数变为 0 的最少操作次数
【动态规划】【位运算】1787. 使所有区间的异或结果为零

【位运算】【脑筋急转弯】2749. 得到整数零需要执行的最少操作数
【数学】【位运算】LeetCoce810. 黑板异或游戏
【位运算】【 数学】【 哈希映射】2857. 统计距离为 k 的点对
【并集查找 图论 位运算】3108. 带权图里旅途的最小代价
【位运算 贪心】2835. 使子序列的和等于目标的最少操作次数
【数学归纳法】【位运算】【异或】3068最大节点价值之和

扩展阅读

视频课程

有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步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.mfbz.cn/a/582348.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

织梦云端:网络信号原理的艺术解码

hello &#xff01;大家好呀&#xff01; 欢迎大家来到我的Linux高性能服务器编程系列之《织梦云端&#xff1a;网络信号原理的艺术解码》&#xff0c;在这篇文章中&#xff0c;你将会学习到网络信号原理以及应用&#xff0c;并且我会给出源码进行剖析&#xff0c;以及手绘UML图…

【树莓派】yolov5 Lite,目标检测,行人检测入侵报警,摄像头绑定

延续之前的程序&#xff1a; https://qq742971636.blog.csdn.net/article/details/138172400 文章目录 播放声音pygame不出声音怎么办&#xff08;调节音量&#xff09;树莓派上的音乐播放器&#xff08;可选&#xff09;命令行直接放歌&#xff08;尝试放mp3歌曲&#xff09; …

数据结构-二叉搜索树(BST)

目录 什么是二叉搜索树 二叉搜索树的特性 (1)顺序性 (2)局限性 二叉搜索树的应用 二叉搜索树的操作 (1)查找节点 (2)插入节点 (3)删除节点 (4)中序遍历 什么是二叉搜索树 如图所示&#xff0c;二叉搜索树&#xff08;binary search tree&#xff09;满足以下条件。…

【Vivado那些事儿】使用 Python 提取 ILA 数据

ILA应该是调试AMD-Xilinx FPGA最常用的IP。 在调试中&#xff0c;我们希望 ILA 中的波形可以提供有关设计问题的所有信息&#xff0c;但情况并非如此。对于复杂的调试&#xff0c;我们还需要将 ILA 捕获的真实数据存储到可以进一步处理的文件中。根据放置 ILA 的位置&#xff0…

C语言阶段的题目解析

前言 我们C语言已经学习的差不多了&#xff0c;但是C语言之中存在的一些问题与难点我们还不一定能够又快又好地解决&#xff0c;为了夯实我们的基础&#xff0c;我们来练习几道稍微有点难度的C语言习题吧 例题一 题目 int main(void) {unsigned char i 7;int j 0;for (; i…

【PyTorch 实战3:YOLOv5检测模型】10min揭秘 YOLOv5 检测网络架构、工作原理以及pytorch代码实现(附代码实现!)

YOLOv5简介 YOLOv5&#xff08;You Only Look Once, Version 5&#xff09;是一种先进的目标检测模型&#xff0c;是YOLO系列的最新版本&#xff0c;由Ultralytics公司开发。该模型利用深度学习技术&#xff0c;能够在图像或视频中实时准确地检测出多个对象的位置及其类别&…

千锤百炼之每日算法(三)

题外话 不会再水了,先把算法任务完成! 正题 第一题 简写单词 规定一种对于复合词的简写方式为只保留每个组成单词的首字母,并将首字母大写后再连接在一起 比如“College English Test"可以简写成“CET",“Computer Science 可以简写为"CS"&#xff0c;I a…

【深度学习】【Lora训练1】StabelDiffusion,Lora训练过程,秋叶包,Linux,SDXL Lora训练

文章目录 一、环境搭建指南二、个性化安装流程三、启动应用四、打开web五、开始训练 19.27服务器 一、环境搭建指南 打造一个高效且友好的开发环境&#xff1a; 项目源码获取&#xff1a; 通过以下命令轻松克隆项目及所有子模块至您的Linux系统&#xff1a; git clone --recu…

《ElementUI 基础知识》el-tabs header 监听鼠标中键滚动时左右滑动(ElementPlus同样适用)

前言 收到需求&#xff0c;可监听 el-tabs 头在鼠标 hover 时。滑动鼠标中键&#xff0c;可左右滑动&#xff01; 效果 鼠标中键上下滑动时&#xff1b;向上滑&#xff0c;向左移动&#xff1b;向下滑&#xff0c;向右移动&#xff1b; 实现 代码56 - 60行&#xff0c;添加…

寝室快修|基于SprinBoot+vue的贵工程寝室快修小程序(源码+数据库+文档)

贵工程寝室快修目录 目录 基于SprinBootvue的贵工程寝室快修小程序 一、前言 二、系统设计 三、系统功能设计 1学生信息管理 2 在线报修管理 3公告信息管理 4论坛信息管理 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&a…

操作系统安全:安全审计,Windows系统日志详解,Windows事件ID汇总

「作者简介」&#xff1a;2022年北京冬奥会网络安全中国代表队&#xff0c;CSDN Top100&#xff0c;就职奇安信多年&#xff0c;以实战工作为基础对安全知识体系进行总结与归纳&#xff0c;著作适用于快速入门的 《网络安全自学教程》&#xff0c;内容涵盖系统安全、信息收集等…

C++深度解析教程笔记2

C深度解析教程笔记2 第3课 - 进化后的 const 分析实验-C与C的const区别实验-C与C的const区别&const作用域 第4课 - 布尔类型和引用小结 本文学习自狄泰软件学院 唐佐林老师的 C深度解析教程&#xff0c;图片全部来源于课程PPT&#xff0c;仅用于个人学习记录 第3课 - 进化后…

Unity 递归实现数字不重复的排列组合

实现 private void Permutation(List<int> num, int leftIndex, List<string> strs) {if (leftIndex < num.Count){for (int rightIndex leftIndex; rightIndex < num.Count; rightIndex){Swap(num, leftIndex, rightIndex);Permutation(num, leftIndex 1…

HarmonyOS 鸿蒙下载三方依赖 ohpm环境搭建

前言 ohpm&#xff08;One Hundred Percent Mermaid &#xff09;是一个集成了Mermaid的命令工具&#xff0c;可以用于生成关系图、序列图、等各种图表。我们可以使用ohpm来生成漂亮且可读性强的图表。 本期教大家如何搭建ophm环境&#xff1a; 一、在DevEco Studio中&#…

前端可以掌握的nginx相关操作

一、前言&#xff1a; 在日常开发中&#xff0c;前端工程师可以把打好的前端包直接放到测试服务器上&#xff0c;自己再验证功能是否改好&#xff0c;这样可以提高开发效率&#xff0c;写篇笔记记录一下我个人用到的命令 二、使用的工具 用MobaXterm完成相关操作&#xff0c…

Vue3 + TS 项目实战 - 后台管理系统 - 按钮权限

前期回顾 网站的打赏 —— 新一代的思路-CSDN博客https://blog.csdn.net/m0_57904695/article/details/136704914?spm1001.2014.3001.5501 目录 &#x1f6a9; XX银行_系统管理_按钮权限控制_前端_提测单 项目信息 提测版本信息 功能列表 测试范围 测试环境 ✅ 步…

[paper note]代码生成评估模型-CodeBLEU原理分析

论文信息 论文标题&#xff1a;CodeBLEU: a Method for Automatic Evaluation of Code Synthesis 发表时间&#xff1a;2020年9月 论文原文&#xff1a;CodeBLEU: a Method for Automatic Evaluation of Code Synthesis 论文内容 摘要 评价指标对一个领域的发展起着至关重…

大厂常见算法50题-替换空格

专栏持续更新50道算法题&#xff0c;都是大厂高频算法题&#xff0c;建议关注, 一起巧‘背’算法! 文章目录 题目解法一 String类replace方法解法二 遍历替换总结 题目 解法一 String类replace方法 String类自带的replace&#xff0c;方法传入两个char类型的参数&#xff0c;分…

分类预测 | Matlab实现CNN-GRU-SAM-Attention卷积门控循环单元融合空间注意力机制的数据分类预测

分类预测 | Matlab实现CNN-GRU-SAM-Attention卷积门控循环单元融合空间注意力机制的数据分类预测 目录 分类预测 | Matlab实现CNN-GRU-SAM-Attention卷积门控循环单元融合空间注意力机制的数据分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.Matlab实现CNN-GRU…

蓝牙低能耗安全连接 – 数值比较

除了 LE Legacy 配对之外&#xff0c;LE Secure Connections 是另一种配对选项。 LE 安全连接是蓝牙 v4.2 中引入的增强安全功能。它使用符合联邦信息处理标准 (FIPS) 的算法&#xff08;称为椭圆曲线 Diffie Hellman (ECDH)&#xff09;来生成密钥。对于 LE 安全连接&#xff…