位运算
- 概念
- 位运算模板
- 模板题
概念
异或(x⊕y或x ^ y)
高低位交换:https://www.luogu.com.cn/problem/P1100
题意:给定一个32 3232位整数x xx,在二进制下交换其前16 1616位与后16 1616位,输出最终的数。
答案为ans = (x >> 16) | (x << 16)
注意此处使用32 3232位无符号整数进行计算,这样x << 16会自然溢出,导致前16 1616位被丢弃,恰好满足要求。
参考:
#include <cstdio>
using namespace std;
int main()
{
unsigned int x;
scanf("%u", &x);
printf("%u\n", (x >> 16) | (x << 16));
return 0;
}
位运算模板
求n的第k位数字: n >> k & 1
返回n的最后一位1:lowbit(n) = n & -n
1.求n的第k位数字 : n>>k&1 (n右移k位, 然后&1)
int n = 15; //00000000000000000000000000001111
for(int i=31;i>=0;i--){
System.out.print( n>>i & 1 ); //00000000000000000000000000001111
}
2.返回n的最后一位1 : lowbit(n) = n & -n 这里的 -n 也就是 ~n+1(取反加一)
public static int lowbit(int n){
return n & -n;
}
lowbit(x)即为二进制下x xx的最低位,如lowbit(10010) = 10、lowbit(1) = 1。严格来说0没有lowbit,部分情况下可视为lowbit(0) = 1。利用lowbit函数可实现树状数组等数据结构。
模板题
AcWing 801. 二进制中1的个数
输入样例:
5
1 2 3 4 5
输出样例:
1 1 2 1 2
思路 : 使用 lowbit(n) 依次算出每个末尾1的数 然后减去后继续 lowbit
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
const int N=1e5+10;
int a[N];
int b[N];
int lowbit(int x)
{
return x&(-x);
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
int n;
cin>>n;
while(n--)
{
int x;
cin>>x;
int cnt=0;
while(x)
{
x-=lowbit(x);//减去最后一个1以及后面的数(二进制)
cnt++;
}
cout<<cnt<<" ";
}
}