位运算是直接对整数的二进制位进行操作的运算符,属于 C++ 基础运算中的重要一类。GESP 5 级要求掌握四种:
| 运算符 | 名称 | 规则 |
|---|---|---|
& | 按位与 AND | 两位都为 1 才得 1 |
| | 按位或 OR | 任一为 1 就得 1 |
^ | 按位异或 XOR | 不同为 1,相同为 0 |
~ | 按位取反 NOT | 0→1,1→0(包括符号位) |
& 取交集,| 取并集,^ 取差集。~ 是"全部翻转",注意 ~0 = -1(补码全1)。
易错重点:位运算优先级低于比较运算符 == !=,所以 a & b == 0 实际等价于 a & (b == 0),必须加括号:(a & b) == 0。
# 输出:a & b = 8, a | b = 14, a ^ b = 6, ~a = -13, (a & b)==0 ? 0, a & (b==0) = 0, a ^ a = 0, a ^ 0 = 12
(5 ^ 3) & 6 的结果是?~0 的结果(32位 int)是?x & (x-1) 技巧:每次消去最低位的 1。
#include<iostream>
using namespace std;
int main(){
int a,b;
cin>>a>>b;
int x=a^b; // 异或:不同位变1
int cnt=0;
while(x){
x=x&(x-1); // 消去最低位的1
cnt++; // 每消一个就+1
}
cout<<cnt<<endl;
return 0;
}
& | ^ 的优先级低于 == !=,涉及比较时必须加括号。~0 = -1(不是最大的正整数),~n = -(n+1)(对正整数成立)。a^a=0、a^0=a、a^b=b^a(交换律)、可结合。这是无变量交换和找"只出现一次的数"的基础。mask |= (1<<i) 置位,mask & (1<<i) 查位,mask & ~(1<<i) 清位——这在 8 级状压 DP 中是核心。