比如一个集合(5,8,3,6,78,45,33,22),我们可以用一个n位的2进制数表示这个集合。
比如11111111代表这个全集,而10100000代表(5,3)这个子集(二进制中1代表这个子集中有全集中相应位置的数字)
像这样表示后,一些集合运算可以对应地写成如下方式:(全集按6个元素)
空集......................................................................0
只含有第i个元素的集合{i}.....................................1<<i (1<<2=4(10进制)=000100(2进制),1<<4=010000)
只含有全部n个元素的集合{0,1,2,....n-1}...............(1<<n)-1 (1<<6=1000000 1<<6-1=0111111)
判断第i个元素是否属于集合S...............................if(S>>i&1)
向集合中加入第i个元素SU{i}................................S|1<<i
从集合中去除第i个元素S\{i}..................................S&~(1<<i)
集合S和T的并集....................................................S|T
集合S和T的交集....................................................S&T
将集合{0,1,2,....n-1}所有子集枚举出来
for(s=0;s<1<<n;s++)
{//接下来的操作。
}
枚举某个集合(这个集合本身是别人的子集 比如0111000)的子集
t=s;//对s这个子集不断递减1,查询其子集
do
{
t=(t-1)&t;
}while(t!=s)//处理完0之后,会有-1&s=s
枚举{0,1,2....n-1}所包含的所有大小为k的子集
comb=(1<<k)-1;
while(comb<1<<n)
{
x=comb&-comb,y=comb+x;
comb=((comb&~y)/x>>1)|y;//comb就是大小为k的子集
}