今天看K神的一篇题解, 看到一些关于位运算的技巧。 又想起以前学长川哥给的一篇位运算对集合处理的技巧的pdf。 所以就一起整理一下。
各种位运算符的功能就不累述了。
集合的位运算表示(来自川哥给的pdf)
基本表示
1.空集 0
2.全集(1<<n)-1
3.只含有第 i 个元素的集合1<<i
集合间的操作
1.s 与 t 的并集 s|t
2.s 与 t 的交集 s&t
3.从 s 中删除其子集 t s^=t
集合与元素的操作
1.判断 s 中是否有第 i 个元素if(s&(1<<i)) 或者 if((s>>i)&1)
2.向 s 中添加第 i 个元素 (将 s 的第 i 位,置为 1)s|=(1<<i)
3.从 s 中删除第 i 个元素(即使不存在)(将 s 的第 i 位,置为 0)s&=(~(1<<i))
集合枚举
1.枚举全集的所有子集for(int s=0;s<(1<<n);s++)
2.枚举集合 s 的所有非空子集for(int t=s;t;t=(t-1)&s)
3.枚举含有 k 个元素的所有集合
int comb = (1<< k) – 1
while ( comb< ( 1<<n ) )
{
int x = comb & -comb, y = comb + x;
comb=( (comb & -y) / x >> 1) | y;
}
特别的:
位运算的优先级特别低,比比较符号还要低!比如 s&t == 1 的实际意义是 s &(t==1)而不是(s&t)==1 所以遇到位运算的相关操作,最好加上括号.
位运算对数位的处理(来自K神博客)
K神博客:http://blog.csdn.net/u013451221/article/details/38679153
将s中二进制第k位变成0的处理方式:
s = s & (~(1 << pos));
将s中二进制第k位变成1的处理方式:
s = s | (1 << pos);
快速判断奇偶性:
if(a & 1)//a为奇数
if(!(a & 1))//a为偶数
交换2个值不运用临时变量:
a = a ^ b;
b = b ^ a;
a = a ^ b;