算法竞赛进阶指南 第一章基本算法 第一节 位运算 总结

本文深入探讨了位运算符的使用,包括与、或、非、异或等,以及它们在二进制状态压缩中的应用。详细解释了如何通过位运算进行状态查询、修改和赋值,介绍了lowbit运算及其在查找二进制中1位的应用。此外,还提供了两种基于lowbit运算和Hash的方法来高效处理整数二进制表示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

&      与            两者都为1则为1,有一个不为1则为0

|       或            有一个为1则为1,都为0则为0

!     非            取反 0对应1,false对应true (逻辑取反)

~      非            按位取反,0变为1,1变为0

^    异或           两者相同为0,不同为1

 

~x+1表示一个数的补码

-n=~n+1

移位运算

左移    <<         在二进制表示形式下把数字同时向左移动,低位以0填充,高位越界后舍弃

算术右移          在二进制补码表示下把数字同时向右移动,高位以符号位填充,低位越界后舍弃

二进制状态压缩

/*
取出整数 n 在二进制表示下的第 k 位                      (n >> k) & 1 
取出整数 n 在二进制表示下的第 0 ~ k-1 位(后k位) 		n & ((1 << k) - 1)
把整数 n 在而今汉字表示下的第 k 位取反                  n ^ (1 << k)
对整数 n 在二进制表示下的第 k 位赋值1                   n | (1 << k) 
对整数 n 在二进制表示下的第 k 位赋值0                   n & (~ (1 << k))  
*/

成对变换 

       当 n 为 偶数时 n^1 等于n+1 

        当 n 为 奇数时 n^1 等于n-1

       因此,“0与1”“2与3”“4与5”。。。。关于x^1运算构成“成对变换”

       这个性质经常用于图论邻接表中边集的存储,

lowbit运算

     lowbit(n)定义为非负整数 n 在二进制表示下“最低位的1及其后边所有的0”构成的数值

     设 n>0 ,n的第k位为1,第 0~k-1 位都是0

    先把n取反,此时第k位为0,第 0~k-1 位都是1,再令n=n+1 此时因为进位,第k位变为1,第 0~k-1 位都是0

    在上面的取反加一操作后,n的第k+1到最高位恰好与原来相反,所以n&(~n+1)仅有第k位为1,其余位都是0,而在补码表示下~n+1=-n

所以:   lowbit(n)=n&(~n+1)=n&-nzhao

lowbi运算配合Hash可以找出整数二进制表示下所有是1的位,所花费的时间与1的个数同级

两种方法

#include<iostream>

using namespace std;
int H[37];
int main(){
	for(int i = 0; i < 36; i++) H[(1ll << i)%37] = i;
	int n;
	while(cin >> n){
		while(n >0){
			cout << H[(n & -n)% 37] <<" ";
			n -= n & -n;
		}
		cout << endl;
	}
}
#include <iostream>

using namespace std;
const int MAX_N =1<<20;
int H[MAX_N + 1];
int main(){
int n;
for(int i = 0; i <= 20; i++) H[ 1 << i] = i;
while(cin>>n){
	while(n > 0){
		cout<<H[n&-n]<<" ";
		n -= n & -n;
	}
	cout<<endl;
}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值