【数学】快速幂

· · 个人记录

首先,快速幂的目的就是做到快速求幂,假设我们要求a^b,按照朴素算法就是把a连乘b次,这样一来时间复杂度是O(b)也即是O(n)级别,快速幂能做到O(logn),快了好多好多。它的原理如下:

假设我们要求a^b,那么其实b是可以拆成二进制的,该二进制数第i位的权为2^(i-1),例如当b==11时

        a^11=a(2^0+2^1+2^3)

11的二进制是1011,11 = 2³×1 + 2²×0 + 2¹×1 + 2º×1,因此,我们将a¹¹转化为算 a2^0*a2^1*a2^3,也就是a1*a2*a8 ,看出来快的多了吧原来算11次,现在算三次,但是这三项貌似不好求的样子

由于是二进制,很自然地想到用位运算这个强大的工具:&和>> &运算通常用于二进制取位操作,例如一个数 & 1 的结果就是取二进制的最末位。还可以判断奇偶x&1==0为偶,x&1==1为奇。 >>运算比较单纯,二进制去掉最后一位

常规求幂

        int pow1(int a,int b){
           int r=1;
           while(b--) r*=a;
           return r;
        } 

快速求幂(一般)

        int pow2(int a,int b){
            int r=1,base=a;
            while(b!=0){
            if(b%2) r*=base;
            base*=base;
            b/=2;
            }
            return r;
        }

快速求幂 (递归)

        int f(int m,int n){   //m^n
            if(n==1) return m;
            int temp=f(m,n/2);
            return (n%2==0 ? 1 : m)*temp*temp;
        }

快速求幂(位运算)

        int pow3(int x,int n){
          if(n==0) return 1;
          else {
            while((n&1)==0){
              n>>=1;
              x*=x;
            }
          }
          int result=x;
          n>>=1;
          while(n!=0){
            x*=x;
            if(n&1) result*=x;
            n>>=1;
          }
          return result;
        }

快速求幂(位运算,更简洁)

        int pow4(int a,int b){
          int r=1,base=a;
          while(b){
            if(b&1) r*=base;
            base*=base;
            b>>=1;
          }
          return r;
}