lowbit
lowbit 函数
定义
lowbit(n)
定义为非负整数 \(n\) 在二进制表示下最低位的 \(1\) 所对应的值。
任一非负整数都可被表示一个二进制数:
\[(5)_{10}=(101)_2
\]
\[(6)_{10}=(110)_2
\]
而 lowbit 是这样的,设一个非负整数 \(n\) 在二进制表示下最低位的 \(1\) 为从左往右数第 \(k\) 位,\(lowbit(n)=2^{k-1}\)。
例如:
\[lowbit(5)=(1)_{2}=(1)_{10}
\]
\[kowbit(6)=(10)_{2}=(2)_{10}
\]
实现
lowbit(n)=n&(-n)
设 \(n\) 为非负整数,二进制下第 \(k\) 位为 \(1\),第 \(1\) 到 \(k-1\) 位为 \(0\)。
拿 \((14)_{10}=(01110)_{2}\) 来举例:
先将 \(14\) 取反,取反后为 \((10001)_{2}\),再加 \(1\),变为 \((10010)_{2}\)。这时候与原来相比,只有第 \(1\) 到 \(2\) 位相同,其他相反,再相与,最终得到的就是 \(lowbit(n)\)。
而在补码表示下 ~n=-1-n
,即 -n=~n+1
,所以 lowbit(n)=n&(-n)
。
应用
统计 1 的个数
一直进行 lowbit,不断减去直到为 \(0\)。
while(x)
{
x-=x&-x;
cnt++;
}
找出所有为 1 的位
lowbit 配合 hash,即可做到找出所有为 1 的位。
const int N=1<<20;
int H[N+5];
for(int i=0;i<=20;i++) H[1<<i]=i;//代替 log 运算
while(x)
{
cout<<H[x&-x]<<" ";
x-=x&-x;
}