位运算
位运算
1、用途
广泛用于加快枚举速度以及实现各种黑科技
2、原理
几个基本操作:与(&)、或(|)、非(~)、异或(^)、左移(<<)、右移(>>)。
[egin{array} {c|cc} ext{&} & 0 & 1\ hline 0 & 0 & 0\ 1 & 0 & 1end{array}
]
[egin{array} {c|cc} ext{|} & 0 & 1\ hline 0 & 0 & 1\ 1 & 1 & 1end{array}
]
[egin{array} {c|cc} ext{~} & 0 & 1\ hline ext{} & 1 & 0end{array}
]
[egin{array} {c|cc} ext{^} & 0 & 1\ hline 0 & 0 & 1\ 1 & 1 & 0end{array}
]
注:位运算有以下性质
①(a&ble a+b)
②(a ext{^}0=a)
③(a ext{^}a=0)
④(a+b=a ext{^}b+2(a&b))
⑤(a ext{^}b=( ext{~}x & y) | (x & ext{~}y))
3、模板
数字操作
取(n)的第(k)位数字
n >> k & 1
返回(n)的最后一位(1)
lowbit(n) = n & -n
删除(n)的最后一位(1)
n & (n - 1)
判断(n)是否是(2)的幂
n && !(n & (n - 1)) //是2的幂并且非0返回1
判断两数是否异号
(x ^ y) < 0 //异号返回1
字符操作
大小写转换
ch ^ ' ' //大写转小写,小写转大写
转小写
ch | ' '
转大写
ch & '_'
集合操作
取空集
0
仅含第(i)个元素((ige0))的集合
1 << i
含有全部(n)个元素的集合((0le i<n))
(1 << n) - 1
插入第(i)个元素
S | (1 << i)
删除第(i)个元素
S & ~(1 << i)
两个集合的并集
S | T
两个集合的交集
S & T
枚举子集
int sub = sup;
do
{
//operations
sub = (sub - 1) & sup;
}
while (sub != sup);
枚举大小为(k)的子集
int comb = (1 << k) - 1;
while (comb < 1 << n)
{
//operations
int x = comb & -comb, y = comb + x;
comb = ((comb & ~y) / x >> 1) | y;
}
利用遮罩选取两集合中的特定元素
(a & ~mask) | (b & mask)
例题
Codeforces 1312C Adding Powers