位运算与快速幂
记一下快速幂,感觉蛮有意思的。
(a * b) % p = (a % p * b % p) % p
任意一个(0~2k)的数能够表示为(1,2,4……2k)中的数相加的形式
类似于多重背包的优化
二进制真是一个神奇的东西
例题:
1 #include <bits/stdc++.h> 2 #define endl '\n' 3 #define x first 4 #define y second 5 #define int long long 6 #define Tang ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); 7 8 using namespace std; 9 10 const int N=1e5+10; 11 const int INF=0x3f3f3f3f; 12 const int mod=1e9+7; 13 14 void solve() 15 { 16 17 int a,b,p; 18 cin >> a >> b >> p; 19 int ans=1%p; //防止数据中的 b=0 && p=1 20 while(b) 21 { 22 if(b & 1) //二进制的表示中最后一位如果是1 23 ans=ans*a%p; 24 a=a*a%p; 25 b >>= 1; //二进制中去掉一位 26 } 27 cout << ans << endl; 28 29 } 30 31 signed main() 32 { 33 Tang 34 int T=1; 35 //cin >> T; 36 while(T--) 37 solve(); 38 39 return 0; 40 41 }
1 #include <bits/stdc++.h> 2 #define endl '\n' 3 #define x first 4 #define y second 5 #define int long long 6 #define Tang ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); 7 8 using namespace std; 9 10 const int N=1e5+10; 11 const int INF=0x3f3f3f3f; 12 const int mod=1e9+7; 13 14 void solve() 15 { 16 17 int a,b,p; 18 cin >> a >> b >> p; 19 int ans=0; 20 while(a) 21 { 22 if(a&1) 23 ans=(ans+b)%p; 24 b=b*2%p; 25 a >>=1; 26 } 27 cout << ans << endl; 28 29 } 30 31 signed main() 32 { 33 Tang 34 int T=1; 35 //cin >> T; 36 while(T--) 37 solve(); 38 39 return 0; 40 41 }
& 与
运算规则:只有两个数的二进制同时为1,结果才为1,否则为0。(负数按补码形式参加按位与运算)
即 0 & 0= 0 ,0 & 1= 0,1 & 0= 0, 1 & 1= 1。
例:3 &5 即 00000011 & 00000101 = 00000001 ,所以 3 & 5的值为1。
| 或
运算规则:参加运算的两个数只要两个数中的一个为1,结果就为1。
即 0 | 0= 0 , 1 | 0= 1 , 0 | 1= 1 , 1 | 1= 1 。
例:2 | 4 即 00000010 | 00000100 = 00000110 ,所以2 | 4的值为 6 。
~ 非
运算规则:参加运算的两个数,如果两个相应位为“异”(值不同),则该位结果为1,否则为0。
即 0 ^ 0=0 , 0 ^ 1= 1 , 1 ^ 0= 1 , 1 ^ 1= 0 。
例: 2 ^ 4 即 00000010 ^ 00000100 =00000110 ,所以 2 ^ 4 的值为6 。
^ 异或 >> 右移 << 左移 常用操作: 求x的第k位数字 x >> k & 1 lowbit(x) = x & -x,返回x的最后一位1