编程改变世界
快速幂(ab):它基于二分法的思想,因此也常被称为二分幂,快速幂基于以下事实:
如果b是奇数,那么有ab = a * ab -1
如果b是偶数,那么有ab = a(b/2) * a(b/2)。
显然,b是奇数的情况总是可以在下一步转换为b是偶数的情况,而b是偶数的情况总可在下一步转换为b/2的情况。这样,在 log(b) 级别次数的转换后,就可以把b变成0,而任何正整数的0次方都是1.
所以时间复杂度为O(logb)
代码如下:
public static long bin(long a,long b,long k){
if (b == 0) return 1 % k;
//为了特殊情况,这里也要 % k,(bin(1,0,1))
if (b % 2 == 1){
return (a * bin(a, b - 1, k)) % k;
}else {
long mul = bin(a, b / 2, k);
return mul * mul % k;
//这里不能写成 bin(a, b / 2, k) * bin(a, b / 2, k)
//这样的话时间要调用两次,时间复杂度会大大增多。
}
}
测试运行代码(洛谷P1226题):
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
long a = input.nextInt();
long b = input.nextInt();
long k = input.nextLong();
System.out.printf("%d^%d mod %d=%d%n",a,b,k,bin(a,b,k));
}
public static long bin(long a,long b,long k){
if (b == 0) return 1 % k;
if (b % 2 == 1){
return (a * bin(a, b - 1, k)) % k;
}else {
long mul = bin(a, b / 2, k);
return mul * mul % k;
}
}
}
运行结果: