当我翻博客时发现前面的题目没有题目链接实在是太伤了,从这篇开始加题目链接,之前的有时间就补上。
这节主要介绍两种常用的位运算操作:
- 一个整数n的二进制表示中第k位是什么:
n >> k & 1
- 返回整数x的二进制表示的最右一位1:
x & -x
或x & (-x + 1)
1 整数n的二进制表示的第k位
首先约定个位是第0位,找到第k位需要两步:
- 先把第k位移到最右一位即n >> k
- &1
合一起就是 n >> k & 1
引申应用:返回某一个数的二进制表示(即依次输出各个位)
#include<iostream>
using namespace std;
int main(){
int n = 15;
for(int k = 3; k >= 0; k --) cout << (n >> k & 1);
return 0;
}
上面代码运行的结果是:1111
2 返回最右一位1
返回最右一位1的操作我们通常会定义 lowbit() 函数去实现,这个函数是树状数组的基本操作。(假装懂了)
举个例子:lowbit(1010) = 10; lowbit(101000) = 1000
实现方法:x & (-x + 1)
或者 x & -x
都可以。
x & (-x + 1)就是原码和补码相与的结果。
eg.101000
- 原码:101000
- 补码:011000
- 相与:001000
最简单的应用:统计1的个数
int lowbit(int x){
return x & -x;
}
//main
int res = 0;
while(x){
x -= lowbit(x);
res ++;
}
题目链接:https://www.acwing.com/problem/content/803/
代码:
#include<iostream>
using namespace std;
const int N = 100010;
int lowbit(int x){
return x & (-x);
}
int main(){
int n;
cin >> n;
while(n --){
int x;
int res = 0;
scanf("%d", &x);
while(x){
x -= lowbit(x);
res ++;
}
printf("%d ", res);
}
return 0;
}