二进制表示集合

  • 空集:​​0​
  • 只有第 i 个元素的集合:​​1<<i​
  • 含有全部 n 个元素的集合:​​(1<<n)-1​
  • 判断第 i 个元素是否属于集合 S:​​if(S>>i&1)​
  • 向集合中加入第 i 个元素:​​S|1<<i​
  • 从集合中去除第 i 个元素:​​S&~(1<<i)​
  • 集合 S 和 T 的并集:​​S|T​
  • 集合 S 和 T 的交集:​​S&T​

枚举\(\{0,1,...,n-1\}\)的所有子集:

for(int S=0;S<1<<n;S++){ //对子集的处理 }

枚举 sup 的所有子集:

int sub=sup; do{ //对子集的处理 sub=(sub-1)&sup; }while(sub!=sup); //-1&sup=sup结束循环

枚举\(\{0,1,...,n-1\}\)的所有子集大小为 k 的集合的方法:

int comb=(1<<k)-1; while(comb<1<<n){ //对集合的处理 int x=comb&-comb,y=comb+x; comb=((comb&~y)/x>>1)|y; }

①​​x&(-x)​​的值就是将其最低位的1独立出来后的值

②​​y=comb+x​​就是将 comb 从最低位的1开始的连续的1都置0了

③​​z=comb&-y​​得到了最低位1开始的连续区间

④​​z/x​​可以将 z 不断右移,直到最低位为1