文章目录
- 前言
- 一、快速幂
- 二、二进制运算和状态压缩DP
- 三、用异或求配偶
- 四、lowbit运算(求最低位的1)
前言
一、或,且,非,异或(x^y)(相同—>0; 不同—>1)
二、补码:
int 32位
1:0000000……01
2:0000000……10
3:0000000……11
x + ? = 00000000……00
? = ~x + 1(取反加一)
~x + 1 是 x 的补码, 即 -n = ~n + 1(1是二进制的1)
三、无穷大
memset(f, 0x3F, sizeof(f));
因为0x3f3f3f3f * 2 < 0xfffffff(无穷大)
四、算数左右移
左移:1->10->100
1 << n = 2 ^n
右移:n >> x = n / 2 ^ x;
逻辑右移就是不考虑符号位,右移一位,左边补零即可。
算术右移需要考虑符号位,右移一位,若符号位为1,就在左边补1,;否则,就补0。
所以算术右移也可以进行有符号位的除法,右移,n位就等于除2的n次方。
例如,8位二进制数11001101分别右移一位。
逻辑右移就是[0]1100110
算术右移就是[1]1100110
提示:以下是本篇文章正文内容,下面案例可供参考
一、快速幂
#include <iostream>
using namespace std;
int main(){
int a, b, q;
cin >> a >> b >> q;
int res = 1 % q;
while(b){
if (b & 1) res = res * 1ll * a % q;
a = a * 1ll * a % q;
b >>= 1;
}
cout << res << endl;
//system("pause");
return 0;
}
二、二进制运算和状态压缩DP
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 20, M = 1 << 20;
int n;
int f[M][N], weight[N][N];
int main(){
cin >> n;
for(int i = 0; i < n; i ++)
for(int j = 0;j < n; j ++)
cin >> weight[i][j];
memset(f, 0x3f, sizeof(f));
f[1][0] = 0;
for(int i = 0; i < 1 << n; i ++)
for(int j = 0; j < n; j ++)
if(i >> j & 1)
for(int k = 0; k < n; k ++)
if(i - (1 << j) >> k & 1)
f[i][j] = min(f[i][j], f[i - (1 << j)][k] + weight[k][j]);
cout << f[(1 << n) - 1][n - 1] << endl;
system("pause");
return 0;
}
三、用异或来实现配偶
0,1
2,3
4,5
6,7
0 ^ 1 = 1, 1 ^ 1 = 0
4 ^ 1 = 5, 5 ^ 1 = 4
用来求正反面
e[inder]
e[inder ^ 1]
四、lowbit运算
lowbit(1110010000) = 10000
0001101111 + 1
0001110000
可写成:
int lowbit(n){
return (-n) & n; //-n = ~n + 1;
}