快速幂求解
顾名思义,快速幂就是快速算底数的n次幂。其时间复杂度为 O(log₂N), 与朴素的O(N)相比效
用法:用于求解 a 的 b 次方,而b是一个非常大的数,用O(n)的复杂度会超时。那么就需要这个算法,注意它不但可以对数求次幂,而且可用于矩阵快速幂。
把b转换成二进制数,该二进制位数有logb位;该二进制数第i位的权为2i-1
例如:
11的二进制是1011
11 = 2³×1 + 2²×0 + 2¹×1 + 2º×1
因此,我们将a¹¹转化为算
对数求次幂:(求a^b次方的值) 时间复杂度为logb
1 public static int Fast_pow(int a, int b){ 2 int ans=1;//存放最后结果 3 int mod = 101;//存放取模值 4 while(b>0) { 5 if(b%2==1){ 6 ans=(ans*a)%mod; 7 } 8 a=(a*a)%mod; 9 b >>= 1; 10 } 11 return ans; 12 }
矩阵求次幂例题:
1 /** 2 * 网易笔试第五题:时间不超过1秒 3 * 输入数据包括两行: 4 * 第一行为两个整数n(2 ≤ n ≤ 50)和k(1 ≤ k ≤ 2000000000),以空格分隔 5 * 第二行为魔力手环初始的n个数,以空格分隔。范围都在0至99. 6 * 输出描述:输出魔力手环使用k次之后的状态,以空格分隔,行末无空格。 7 8 输入例子: 9 3 2 10 1 2 3 11 12 输出例子: 13 8 9 7 14 15 */ 16 17 import java.util.Scanner; 18 19 20 public class Main { 21 private final static int MOD = 100; 22 public static void main(String[] args) { 23 //时间复杂度(n^3)logk 24 Scanner in = new Scanner(System.in); 25 int n = in.nextInt(); 26 int k = in.nextInt(); 27 28 int[][] ans= new int[1][n]; 29 for(int i = 0; i < n; i++){ 30 ans[0][i] = in.nextInt(); 31 } 32 33 //构造满足条件的矩阵 34 int[][] src = new int[n][n]; 35 for(int i = 0; i < n; i++){ 36 37 if(i < (n-1)){ 38 src[i][i] = 1; 39 src[i+1][i] = 1; 40 }else{ 41 src[i][i] = 1; 42 src[0][i] = 1; 43 } 44 } 45 46 //快速矩阵幂 47 while(k > 0){ 48 if(k % 2 == 1){//相当于k&1 49 ans = MatrixMul(ans, src); 50 } 51 src = MatrixMul(src, src); 52 k >>= 1; 53 } 54 55 System.out.print(ans[0][0]); 56 for(int i = 1; i < ans[0].length; i++){ 57 System.out.print(" "+ans[0][i]); 58 } 59 in.close(); 60 } 61 62 /** 63 * 矩阵乘法运算 64 * @param a 矩阵a 65 * @param b 矩阵b a和b满足乘法要求a[0].length==b.length 66 * @return 67 */ 68 public static int[][] MatrixMul(int[][] a,int[][] b){ 69 int[][] tmp = new int[a.length][a[0].length]; 70 71 for(int i = 0; i < a.length; i++){ 72 for(int j = 0; j < b[0].length; j++){ 73 74 for( int k = 0; k < a[0].length; k++){ 75 tmp[i][j] = (tmp[i][j] + a[i][k] *b[k][j])%MOD; 76 } 77 } 78 } 79 return tmp; 80 } 81 }