首页 > 代码库 > 关于快速幂取模

关于快速幂取模

今天看算法书的时候,看到一道关于快速幂取模的题,心想好像不难,便写了一下,发现我的渣渣
代码写的比正常的O(N)复杂度还要慢(天知道我怎么做到的T_T),渣渣代码如下:

 1 public static long fastMi(long x,long n){
 2     if(n==1){
 3         return x;
 4     }
 5     if(n%2==0){
 6         return fastMi(x,n/2)*fastMi(x,n/2);
 7     }else{
 8         return fastMi(x,n/2)*fastMi(x,n/2+1);
 9     }
10 }

于是只好从最基本的复杂度O(N)的算法来看我哪错了
当计算x的n次方余m的值时,正常做法一般是复杂度O(N)的做法,如下:

 1     /**
 2      * @param x
 3      * @param n
 4      * @param m
 5      * @return 返回x^n%m的值
 6      */
 7 public long power(long x,long n,long m){
 8     long result = 1;
 9     for(int i=1;i<=n;i++){
10         result = result * x % m;
11     }
12     return result;
13 }

这种做法就是单纯的基于x的平方等于x*x这种感觉,
不过,如果用上快速幂,那时间复杂度会缩小的log级别,而快速幂
就是基于下面这个观测结果得出的:
  n为偶数时:
    x^n = x^(n/2)*x^(n/2)
  n为奇数时:
    x^n = x * x^(n-1) = x * x^(n-1/2)*x^(n-1/2)

代码如下:

 1 public long power(long x,long n,long m){
 2     if(n==0){
 3         return 1;
 4     }
 5     result = power(x,n/2,m);
 6     if(n%2==0){
 7         return result*result;
 8     }else{
 9         return result*result*x;
10     }
11 }

于是发现我原本的做法又多了几道递归的分支路线,而原本是根本不需要那些分支路线的,只需要一次赋值等于就好了= =

关于快速幂取模