|
| 1 | +- [位运算基本概念](#位运算基本概念) |
| 2 | +- [位运算基本操作](#位运算基本操作) |
| 3 | +- [位运算题型](#位运算题型) |
| 4 | + - [Acwing.801 二进制中1的个数](#acwing801-二进制中1的个数) |
| 5 | + |
| 6 | +*** |
| 7 | +### 位运算基本概念 |
| 8 | +位运算就是基于整数的二进制表示进行的运算。由于计算机内部就是以二进制来存储数据,位运算是相当快的。 |
| 9 | + |
| 10 | +| | 与 | 或 | 异或 | |
| 11 | +| :----: | :-----------------------: | :-----------------------: | :--------------------: | |
| 12 | +| 运算符 | & | \| | ^ | |
| 13 | +| 表示 | 两个对应位都为 1 时才为 1 | 两个对应位都为 0 时才为 0 | 两个对应位不同时才为 1 | |
| 14 | + |
| 15 | +假设数字 $x$ 的源码是 |
| 16 | +1010000100101 |
| 17 | +反码是源码取反,`~x` |
| 18 | +0101111011010 |
| 19 | +补码是源码取反 +1 `~x + 1` |
| 20 | +0101111011011 |
| 21 | + |
| 22 | +### 位运算基本操作 |
| 23 | +输出数字 $x$ 二进制表示的第 $i$ 位数字 |
| 24 | +- 原理:将第 $i$ 位右移 $i$ 移到最低位上,和 1ドル$ 做与的运算,如果第 $i$ 位为 0ドル,ドル则输出 0ドル,ドル如果第 $i$ 位为 1ドル,ドル则输出 1ドル,ドル这样就取出了第 $i$ 位数字 |
| 25 | +``` |
| 26 | +int find(int x, int i){ |
| 27 | + return x >> i & 1; |
| 28 | +} |
| 29 | +``` |
| 30 | +删除数字 $x$ 的最后一位 1ドル$ |
| 31 | +- 原理:如果 $x$ 的二进制表示为 1101000ドル,ドル那么 $x-1$ 二进制表示为 1100111ドル,ドル`x & (x - 1)`计算的结果为 1100000ドル,ドル最后一位 1ドル$ 变成了 0ドル,ドル其它位不变 |
| 32 | +``` |
| 33 | +x & (x - 1); |
| 34 | +``` |
| 35 | +返回数字 $x$ 的最后一位 1ドル$ |
| 36 | +- 原理:如果 $x$ 的二进制表示为 1101000ドル,ドル那么 $~x$ 二进制表示为 0010111ドル,ドル$~x+1$ 二进制表示为 0011000ドル,ドル`x & (~x+1) == x & (-x)`的计算结果为 0001000ドル$ 只保留了最后一位 1ドル,ドル其余位都为 0ドル$ |
| 37 | +``` |
| 38 | +int lowbit(int x){ |
| 39 | + return x & (-x); |
| 40 | +} |
| 41 | +``` |
| 42 | +### 位运算题型 |
| 43 | +#### Acwing.801 二进制中1的个数 |
| 44 | +- 链接<https://www.acwing.com/problem/content/description/803/> |
| 45 | + |
| 46 | +给定一个长度为 $n$ 的数列,请你求出数列中每个数的二进制表示中 1ドル$ 的个数。 |
| 47 | + |
| 48 | +**输入格式** |
| 49 | +第一行包含整数 $n$。 |
| 50 | + |
| 51 | +第二行包含 $n$ 个整数,表示整个数列。 |
| 52 | + |
| 53 | +**输出格式** |
| 54 | +共一行,包含 $n$ 个整数,其中的第 $i$ 个数表示数列中的第 $i$ 个数的二进制表示中 1ドル$ 的个数。 |
| 55 | + |
| 56 | +**数据范围** |
| 57 | +1ドル≤n≤100000,ドル |
| 58 | +0ドル≤数列中元素的值≤10^9$ |
| 59 | + |
| 60 | +**输入样例:** |
| 61 | +``` |
| 62 | +5 |
| 63 | +1 2 3 4 5 |
| 64 | +``` |
| 65 | +**输出样例:** |
| 66 | +``` |
| 67 | +1 1 2 1 2 |
| 68 | +``` |
| 69 | +- 解题代码 |
| 70 | +``` |
| 71 | +#include <iostream> |
| 72 | + |
| 73 | +using namespace std; |
| 74 | + |
| 75 | +int lowbit(int x){ |
| 76 | + return x & (-x); |
| 77 | +} |
| 78 | + |
| 79 | +int main(){ |
| 80 | + int n; |
| 81 | + cin >> n; |
| 82 | + |
| 83 | + while (n --){ |
| 84 | + int x; |
| 85 | + cin >> x; |
| 86 | + |
| 87 | + int res = 0; |
| 88 | + while (x){ |
| 89 | + x -= lowbit(x);// 也可以 x & (x - 1) 不用lowbit操作 |
| 90 | + res ++; |
| 91 | + } |
| 92 | + |
| 93 | + cout << res << ' '; |
| 94 | + } |
| 95 | + return 0; |
| 96 | +} |
| 97 | +``` |
0 commit comments