- 问题分析:如果使用常规方法,计算
的时间复杂度为O(n),数据量大的时候耗时久。但使用快速幂的话,可以将时间复杂度降低到O(logn).
- 快速幂原理:基于二进制,将正整数n二进制拆分成
, 即
- 打个比方:
(11的二进制是1011) 因此,我们将
转化为
- 代码求解:我们可以利用二进制特性进行求解,从右向左对a的二进制的每一位进行处理,该位为1就进行计算,为0则忽略,将每一位处理得到的结果相乘就得到最终答案。
详细代码:
private static long ksm(long a,long n,long mod){ //求解a的n次方,对mod除余
long res = 1; //初始化最终结果
while(n > 0){
if((n & 1) > 0) {
//如果该二进制位为1,那么进行计算
res = res * a % mod;
}
//n右移一位,进行二进制下一位的计算
n >>= 1;
//相应地,a随之增大
a = a * a % mod;
}
return res;
}
下面给一道练手的题目:
P1226 【模板】快速幂||取余运算 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P1226AC代码:
import java.util.Scanner;
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
//数据输入
Scanner sc = new Scanner(System.in);
int a = sc.nextInt();
int b = sc.nextInt();
int p = sc.nextInt();
long ans = ksm(a,b,p);
System.out.println(a+"^"+b+" mod "+p+"="+ans);
}
private static long ksm(long a,long n,long mod){
long res = 1;
while(n>0) {
if((n & 1) > 0){
res = res * a % mod;
}
a = a * a % mod;
n >>= 1;
}
return res;
}
}