【算法】快速幂
一、概念
快速幂是一种高效的指数运算,当指数范围过大时,通过位运算能够减少大量的计算次数
对于,我们通过将指数b转化为二进制数,就可以将
分解为许多的
(其中i是指数b中对应位为1的位数)
例如,我们可以将13转化为二进制的1101,然后就可以将
分解为:
二、例题
2.1 快速幂
875. 快速幂 - AcWing题库
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
int n;
signed main()
{
cin >> n;
for(int i = 0;i < n; i++)
{
int a, b, p;
cin >> a >> b >> p;
int res = 1;
while(b) //将b转二进制数,按位乘以对应的值
{
if(b & 1) //对应位为1
res = res * a % p;
a = a * a % p;
b >>= 1;
}
cout << res << endl;
}
return 0;
}
2.2 快速幂求逆元
876. 快速幂求逆元 - AcWing题库
关于乘法逆元的定义:
前提:
- 整数b,m互质
- 整数a满足b能够整除a
结论:若存在整数x满足,即
和
对模数m同余,则x是b的逆元,记为
拓展——费马小定理:当模数m为质数时,就是b的乘法逆元
可以看到题中模数p是质数,所以我们可以使用费马小定理求a模p的乘法逆元,就是
但是p的范围很大,因此我们需要用快速幂
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
int n;
signed main()
{
cin >> n;
for(int i = 0;i < n; i++)
{
int a, p;
cin >> a >> p;
if(a % p == 0) //不互质
cout << "impossible" << endl;
else
{
int t = p - 2; //费马小定理
int res = 1;
while(t) //快速幂
{
if(t & 1)
res = res * a % p;
a = a * a % p;
t >>= 1;
}
cout << res << endl;
}
}
return 0;
}