位运算

位运算

位运算

1、用途

广泛用于加快枚举速度以及实现各种黑科技

2、原理

几个基本操作:与(&)、或(|)、非(~)、异或(^)、左移(<<)、右移(>>)。

\[\begin{array} {c|cc} \text{&} & 0 & 1\\ \hline 0 & 0 & 0\\ 1 & 0 & 1\end{array} \]

\[\begin{array} {c|cc} \text{|} & 0 & 1\\ \hline 0 & 0 & 1\\ 1 & 1 & 1\end{array} \]

\[\begin{array} {c|cc} \text{~} & 0 & 1\\ \hline \text{} & 1 & 0\end{array} \]

\[\begin{array} {c|cc} \text{^} & 0 & 1\\ \hline 0 & 0 & 1\\ 1 & 1 & 0\end{array} \]

注:位运算有以下性质

\(a\&b\le a+b\)

\(a\text{^}0=a\)

\(a\text{^}a=0\)

\(a+b=a\text{^}b+2(a\&b)\)

\(a\text{^}b=(\text{~}x \& y) | (x \& \text{~}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\)个元素\((i\ge0)\)的集合
1 << i
含有全部\(n\)个元素的集合\((0\le 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

Codeforces 1395C Boboniu and Bit Operations

Codeforces 1325D Ehab the Xorcist

posted @ 2020-08-29 21:43  Lecxcy  阅读(242)  评论(0)    收藏  举报