快速冪

快速冪

顧名思義,快速冪就是快速算底數的n次冪。其時間複雜度為 O(log2N), 與樸素的O(N)相比效率有了極大的提高。

基本介紹

  • 中文名:快速冪
  • 外文名:Fast Power
  • 時間複雜度:log(n)
  • 性質:快速算底數的n次冪
原理,實現,代碼比較,

原理

以下以求a的b次方來介紹
把b轉換成二進制數
該二進制數第i位的權為
例如
11的二進制是1011
因此,我們將a11轉化為算

實現

快速冪可以用位運算來實現
b and 1{也就是取b的二進制最低位(即第0位) 判斷b是否為奇數,是則為1} 
b shr 1{就是去掉b的二進制最低位(即第0位)} 
C++實現為
b & 1//取b二進制的最低位,判斷和1是否相同,相同返回1,否則返回0,可用於判斷奇偶
b>>1//把b的二進制右移一位,即去掉其二進制位的最低位
以下為pascal的實現:
var a,b,n:int64;function f(a,b,n:int64):int64;var t,y:int64;begin  t:=1; y:=a;  while b<>0 do begin    if(b and 1)=1 then t:=t*y mod n;    y:=y*y mod n;{這裡用了一個技巧,y*y即求出了a^(2^(i-1))不知道這是什麼的看原理                     a^(2^(i-1))*a^(2^(i-1))=a^(2^i)                    而且一般情況下a*b mod c =(a mod c)*(b mod c) mod c}    b:=b shr 1;{去掉已經處理過的一位}  end;  exit(t);end;begin  read(a,b,n);{n是模}  writeln(f(a,b,n));end.
以下為C的實現,為了方便與pascal的對照,變數全部與上面相同.可以對照查看。
遞歸版:
ll pow(ll a,ll i){  if (i==0) return 1;  int temp=pow(a,i>>1);  temp=temp*temp%MOD;  if (i&1) temp=(ll)temp*a%MOD;  return temp%MOD;}
非遞歸版:
ll f(ll a,ll b,ll n){  int t,y;  t=1; y=a;  while (b!=0){    if (b&1==1) t=t*y%n;    y=y*y%n; b=b>>1;  }  return t;}

代碼比較

常規求冪
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;}
完整快速冪代碼
#include<bits/stdc++.h>using namespace std;long long qiuckpower(long long x,long long y){    long long ans=1,cnt=x;    while(y)    {   if(y&1)   {  ans*=cnt;   }   cnt*=cnt;   y>>=1;    }    return ans;}int main(){    long long x,y,ans;    cin>>x>>y;    ans=qiuckpower(x,y);    cout<<ans;    return 0;}

相關詞條

熱門詞條

聯絡我們