位运算

\(\text{lowbit}\) 运算

介绍

对于一个数 \(x\) ,每次读取 \(x\) 二进制表示下的最后面的 \(1\) 所表示的数 ,即 \(lowbit(x)\)

例如:
\(lowbit(7)\) = \(1\).
\(lowbit(4)\) = \(4\).
\(lowbit(6)\) = \(2\).

通过 \(lowbit\) 运算,可以获得一个数二进制下所有是 \(1\) 的位数。

读取最后一位 \(1\) 的方法:

1.令 \(y\) \(=\) \(\sim\) \(x\) \(+\) \(1\)

设最后一位 \(1\) 在第 \(i\) 位。则取反后,\(0\) \(\sim\) \(i - 1\) 位为 \(1\) ,第 \(i\) 位为 \(0\)

再加 \(1\) 就可通过进位,令 \(0\) \(\sim\) \(i - 1\) 位为 \(0\) , 第 \(i\) 位为 \(1\)

2.令 \(num\) \(=\) \(y\) & \(x\)

将两个数相与,就能得到只有第 \(i\) 位为 \(1\) ,其他位都为 \(0\) 的数 \(num\)

\(x\) 减去 \(num\) ,就能减去最后一位 \(1\)

在补码表示下: \(\sim\)n \(=\) \(-\) \(1\) \(-\) \(n\)

\(\sim\) \(n\) \(+\) \(1\) \(=\) \(-\) \(n\)

用处

提取二进制 \(x\) 中所有是 \(1\) 的位数。

\(\text{code}\)

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int main(){
	int x;
	scanf("%d",&x);
	while(x!=0){
		int num=x&-x;
		x-=num;
		cout<<num<<" ";//最后一位 1 与后面的0共同所代表的数 
		cout<<(log(num)/log(2))<<endl;//这个数是二的多少次方 
	}
        return 0;
}

输入

5

输出
1 0

4 2

题目

\(1.\) P7071 优秀的拆分

\(2.\) P7076 [CSP-S2020] 动物园

posted @ 2022-08-08 00:01  k_stefani  阅读(7)  评论(0编辑  收藏  举报