位运算就是基于整数的二进制表示进行的运算。由于计算机内部就是以二进制来存储数据,位运算是相当快的。
与 | 或 | 异或 | |
---|---|---|---|
运算符 | & | | | ^ |
表示 | 两个对应位都为 1 时才为 1 | 两个对应位都为 0 时才为 0 | 两个对应位不同时才为 1 |
假设数字
1010000100101
反码是源码取反,~x
0101111011010
补码是源码取反 +1 ~x + 1
0101111011011
输出数字
- 原理:将第
$i$ 位右移$i$ 移到最低位上,和$1$ 做与的运算,如果第$i$ 位为$0$ ,则输出$0$ ,如果第$i$ 位为$1$ ,则输出$1$ ,这样就取出了第$i$ 位数字
int find(int x, int i){
return x >> i & 1;
}
删除数字
- 原理:如果
$x$ 的二进制表示为$1101000$ ,那么$x-1$ 二进制表示为$1100111$ ,x & (x - 1)
计算的结果为$1100000$ ,最后一位$1$ 变成了$0$ ,其它位不变
x & (x - 1);
返回数字
- 原理:如果
$x$ 的二进制表示为$1101000$ ,那么$~x$ 二进制表示为$0010111$ ,$~x+1$ 二进制表示为$0011000$ ,x & (~x+1) == x & (-x)
的计算结果为$0001000$ 只保留了最后一位$1$ ,其余位都为$0$
int lowbit(int x){
return x & (-x);
}
给定一个长度为
输入格式
第一行包含整数
第二行包含
输出格式
共一行,包含
数据范围
输入样例:
5
1 2 3 4 5
输出样例:
1 1 2 1 2
- 解题代码
#include <iostream>
using namespace std;
int lowbit(int x){
return x & (-x);
}
int main(){
int n;
cin >> n;
while (n --){
int x;
cin >> x;
int res = 0;
while (x){
x -= lowbit(x);// 也可以 x & (x - 1) 不用lowbit操作
res ++;
}
cout << res << ' ';
}
return 0;
}