位运算
- 概念
- 位运算模板
- 模板题
概念
异或(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; //00000000000000000000000000001111for(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<<" ";}
}