位运算学习笔记(快速幂)
-
内容(点击文章右侧目录即可切换):
-
1.快速幂原理及其模版代码
2.判断奇数偶数
3.找出没有重复的数字
1.快速幂
对应到代码层面:
例如让我们求 a 的 b 次方对 p 取模的值。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
int main()
{
int a,b,p;
cin>>a>>b>>p;
int res=1%p;//防止在b为0的情况下没有进入下面循环直接结束
while(b)//从b的最后一位开始算
{
if(b&1)//如果b的最后一位是1
res=(LL)res*a%p;//可能会溢出,进行强制类型转换,把这个数变成一个longlong
a=(LL)a*a%p;//这一次算的是a的x方项,把下一次的(a的x方)^2准备好
b>>=1;//把二进制中去掉最后一位
}
cout<<res;
return 0;
}
快速幂代码模板(最好背过熟练掌握)
int qmi(int a, int b, int p)
{
int res = 1 % p, t = a;
while (b)
{
if (b&1) res = res *1ll* t % p;//1ll 含义为1longlong 把int转换为longlong类型(防止数据溢出int范围)
t = t *1ll* t % p;
b >>= 1;
}
return res;
}
2.判断奇数偶数
判断奇数偶数时,把需要判断的数进行二进制展示的话,只需要判断最后一位是0还是1即可判断出它是奇数还是偶数。
if(n&1)
cout<<n是一个奇数<<endl;
else
cout<<n是一个偶数<<endl;
3.找出没有重复的数字
在一组整形数据中,只有一个数字出现了一次,其他数字都出现了两次,让我们快速找出这两个数字。
在还没学习位运算的时候看到这道题的想法是用一个map去存数字及其出现的次数,最后遍历这个map看看哪个数对应的值为1就可以找到啦。
通过对位运算的学习,得知:两个相同的数异或的结果是 0,一个数和 0 异或的结果是它本身
那么我们对这个数组进行从头到尾的异或操作,由于异或支持交换律和结合律,
所以交换使数组中两个相同的数字先进行异或得到0,最后剩下的数字和0异或得到它本身,即可显示出这个只出现过一次的数字。
int find(int[] arr){
int tmp = arr[0];
for(int i = 1;i < arr.length; i++){
tmp = tmp ^ arr[i];
}
return tmp;
}