子集枚举 二进制
子集枚举之二进制法(好土的名字)
| A中元素 | 1 | 2 | 3 | 4 | 5 | 二进制 |
|---|---|---|---|---|---|---|
| 在\(A_1\)中的出现情况 | 1 | 0 | 1 | 1 | 1 | 11101 |
| 在\(A_2\)中的出现情况 | 1 | 0 | 0 | 1 | 1 | 11001 |
| 在\(A_3\)中的出现情况 | 0 | 0 | 1 | 0 | 0 | 00100 |
| 在\(A_4\)中的出现情况 | 0 | 1 | 1 | 0 | 0 | 00110 |
仅包含第\(i(1\le i \le 5)\)个元素的集合的数字可以用位移运算构造,写成1<<(i-1);包含所有元素的全集为u=(1<<n)-1,空集表示为0。
一些集合的常用关系有以下几种:
- 并集。从元素的选择角度来讲,就是\(A_2\)与\(A_3\)包含的元素合并起来得到\(A_1\)。可以发现,这就是按位或的运算,可表示为
a1 = a2 | a3。 - 交集。2个集合中同时存在的元素组成的集合。当需要表示2个集合的交集时候,可以把表示2个集合的二进制数按位与运算,即
a3 = a1 & a4。 - 包含。集合\(A_2\)的所有元素都在\(A_1\)中出现,说明\(A_1\)包含\(A_2\)。判断\(A_1\)是否包含\(A_2\)可以写成
(a1|a2 == a1) && (a1&a2 == a2)。 - 属于。把某个元素看做为1个集合,取交集检查是否为1即可。如判断第3个元素是否属于集合\(A_1\)可以写成
(1<<(3-1)) & a1。 - 补集。\(A_2\)对于全集的补集就是\(A_4\),可以写成
a4 = a^a2,^为c/c++异或符号。
统计二进制中的1的个数可以使用内建函数 __builtin_popcount(),它能返回一个数二进制数下1的个数;当然也可以逐位确认。
不忘初心方得始终

浙公网安备 33010602011771号