lowbit()
lowbit 运算
定义:自低位的1及其后面所有位为0构成的数值
例如:
n=10= $(1010)_2$ ans=10
推导:
设 n>0 且k位为1,第0~k-1为都为0
先取反在+1
包括最高位
n1=10010000
n2=01101111
n3=01110000
an=00010000 ans=n&(~n+1)
看数值大小还是看原码
正数原码取反+1(正数补码=原码)表示数值大小为 -n
-n=(~n+1)
公式
lowbit(n)=n&(-n)
通过Lowbit求二进制所有是1的位
1 |
|
n=9=(1001)
n1=1=0001
n2=8=1000
规律:n=n-lowbit(n)
通过Hash代替log2();
直接建立vis数组进行标记
1
2
3
4
5
6
7
8
9
10
11
12
13
14#include<iostream>
using namespace std;
const int maxn=1<<20;
int vis[maxn];
int main(){
int n;
cin>>n;
for(int i=0;i<=20;i++) vis[1<<i]=i;//存的是素质代表的位数
while(n){
cout<<vis[ n&-n ]<<" ";
n-=n&(-n);
}
return 0;
}数学技巧
所有的$$ k\in[0,35],2^k \bmod 37 $$的值都不相同
n&(-n)都是 $2^k$次幂 并且对37取mod后的值都不同1
2
3
4
5
6
7
8
9
10
11
12
13
14#include<iostream>
using namespace std;
const int maxn=37;
int vis[maxn];
int main(){
int n;
cin>>n;
for(int i=0;i<=20;i++) vis[(1<<i)%37]=i;
while( n ){
cout<<vis[ (n&(-n))%37 ]<<" ";
n-=n&(-n);
}
return 0;
}
总结:最重要的还是n-=n&(-n)
求出下一个$2^k$次幂
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!