子集枚举 二进制

子集枚举之二进制法(好土的名字)

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。

一些集合的常用关系有以下几种:

  1. 并集。从元素的选择角度来讲,就是\(A_2\)\(A_3\)包含的元素合并起来得到\(A_1\)。可以发现,这就是按位或的运算,可表示为a1 = a2 | a3
  2. 交集。2个集合中同时存在的元素组成的集合。当需要表示2个集合的交集时候,可以把表示2个集合的二进制数按位与运算,即a3 = a1 & a4
  3. 包含。集合\(A_2\)的所有元素都在\(A_1\)中出现,说明\(A_1\)包含\(A_2\)。判断\(A_1\)是否包含\(A_2\)可以写成(a1|a2 == a1) && (a1&a2 == a2)
  4. 属于。把某个元素看做为1个集合,取交集检查是否为1即可。如判断第3个元素是否属于集合\(A_1\)可以写成(1<<(3-1)) & a1
  5. 补集。\(A_2\)对于全集的补集就是\(A_4\),可以写成a4 = a^a2^为c/c++异或符号。

统计二进制中的1的个数可以使用内建函数 __builtin_popcount(),它能返回一个数二进制数下1的个数;当然也可以逐位确认。

posted @ 2021-01-28 17:55  1v7w  阅读(89)  评论(0编辑  收藏  举报