lowbit操作即找到二进制下该数最低位1与其后面的0组成的数,
如一个数为x,我们可以通过将x取反然后+1,这样最低位为1的后面位数都与之前相反,将他们and之后可得,同时我们知道补码中~x=-1-x,所以可化简为lowbit(x)=x&(~x+1)=x&(-x);
#include <iostream>
#include <cstdio>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <cstring>
#include <set>
#include <cmath>
#include <map>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const int MN = 65005;
const int MAXN = 1000005;
const int INF = 0x3f3f3f3f;
#define IOS ios::sync_with_stdio(false)
int n;
int lowbit(int x) {
return x & (-x);
//return x&(~x+1);
}
int main() {
scanf("%d", &n);
printf("%d", lowbit(n));
return 0;
}
同时我们可以用lowbit得到该数的所有是1的位,只要一直减去当前的lowbit直至为0
若想知道它为第几位则可用cmath库中的log函数,但复杂度常数很大,所以我们需要预处理一个数组,通过hash的方式代替log运算
#if 0
const int MAXN_N = 1 << 20;
int H[MAXN_N + 1];
int main() {
int n;
for (int i = 0; i <= 20; i++) {
H[1 << i] = i; //预处理
}
while (cin >> n) {
while (n) {
cout << H[n & -n] << " ";
n -= n & -n;
}
}
cout << '\n';
return 0;
}
#endif
#if 0
//优化一下,建立一个长度为37的数组H;
int H[37];
int main() {
int n;
for (int i = 0; i < 36; i++) {
H[(1ll << i) % 37] = i;
}
while (cin >> n) {
while (n > 0) {
cout << H[(n & -n) % 37] << " ";
n -= n & -n;
}
}
return 0;
}
#endif

5806

被折叠的 条评论
为什么被折叠?



