今天来复习了一下快速幂相关的知识,其实早在初中,我就早知道快速幂的应用,有时,老师让我们计算2的高次方的时候,我就会先算2次方,进而求出4次方,以此类推,我总能算的又快又对,其实这就是快速幂。
https://www.luogu.com.cn/problem/P1226https://www.luogu.com.cn/problem/P1226 作为一种数学工具,明白其原理和推导是十分重要的。
题目描述
给你三个整数 𝑎,𝑏,𝑝,求 mod 𝑝。
输入格式
输入只有一行三个整数,分别代表 𝑎,𝑏,𝑝。
输出格式
输出一行一个字符串 a^b mod p=s
,其中 𝑎,𝑏,𝑝 分别为题目给定的值, 𝑠为运算结果。
输入输出样例
输入 #1复制
2 10 9
输出 #1复制
2^10 mod 9=7
从暴力的角度,我们会进行b次循环,每一次乘上底数就可以了,但是当指数极大时就会tle因此,我们就需要用到快速幂来解决。
正如开头提到的,如例题,2的10次方就可以看作*
,而我们可以一步一步从2次到4次然后是8次,但是我们会发现,其实四次方并没有出现,这就是伟大的二进制的作用了,10的二进制是1010,每一位就刚好对应了我们需要的位数我们只要在对应的1的位数上将答案乘入即可,同时每一次,无论是不是对答案有贡献,都要更新至下一次方,因此我们可以十分方便将时间复杂度优化到O(log)。
下面是代码实现:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int n, m, p;
int quickpow(LL n, int m, int p)
{
int res = 1;
while(m)
{
if(m & 1)
res = res * n % p;
n = n * n % p;
m >>= 1;
}
return res;
}
int main()
{
cin >> n >> m >> p;
cout << n << "^" << m << " mod " << p << "=" << quickpow(n, m, p);
}
由于乘积往往非常大,需要对p取模,而根据乘法性质,我们可以在每一次更新次方和更新答案时都取模,也是一样的结果。