數論.快速冪
公式求冪→二分求冪→快速求冪→快速求冪取模
公式求冪
直接使用C語言的庫函式pow(),pow()函式在math標頭檔案裡
當然用公式求解,似乎很簡單,但是它的時間複雜度較高,為O(n),對於資料較大的問題,十分容易超時
二分求冪
二分冪的時間複雜度相較於第一種有了明顯的優化,達到了O(lgn)
二分求冪的原理可以用下面這張圖表示 :
用遞迴來實現:
int pow(int a,int n)//返回值是a的n次方
{
if(n==0)//遞迴終止條件
return 1;
if(n==1)
return a;
int result=pow(a,n/2);//二分遞迴
result=result*result;//這部分奇數偶數都一樣
if(n%2==1)//如果n是奇數,就要多乘一次
result=result*a;
return result;
}
用非遞迴來實現:
int pow(int a,int n)//返回值是a的n次方
{
int result=1;
while(n!=0)
{
if(n%2==1)//如果n是奇數
result=result*a;//就要多乘一次
a=a*a;
n=n/2;//二分
}
return result;
}
快速冪
快速冪是一種利用b的二進位制特徵來快速求a^b的演算法,藉助了強大的位運算,時間複雜度進一步優化,達到O(log₂N)。
例如:求a的11次方
11的二進位制是1011
11 = 2³×1 + 2²×0 + 2¹×1 + 2º×1
用非遞迴的程式碼實現
int pow(int a,int n)//返回值是a的n次方
{
int result=1,flag=a;
while(n!=0)
{
if(n&1)//如果n是奇數,即
result=result*flag;
flag=flag*flag;
n=n>>1;//n的二進位制右移一位,即n/2
}
return result;
}
快速求冪取模
刷題中讓直接求冪的不多,求冪後取模的卻不少,畢竟求冪結果太大了。
水平所限,只會用二分冪取模,時間複雜度與二分冪一樣O(lgn)。
基本可以在各種比賽中順利通過,也是目前比較常用的方法
原理同樣很簡單,都是小學學過的:積的取餘等於取餘的積取餘 (涉及到同餘定理)
接下來用程式碼實現
int pow(int a,int n,int b)//返回值是a的n次方對b取餘後的值
{
int result=1;
a=a%b;//積的取餘等於取餘的積取餘
while(n>0)
{
if(n%2==1)
result=result*a%b;//n是奇數的話就要多乘一次,原理和前面的二分求冪一樣
n=n/2;//二分
a=a*a%b;//積的取餘等於取餘的積取餘
}
return result;
影響計算機效率的是運算次數,而不是運算結果。
所以前面幾個演算法都是通過增大運算結果,減少運算次數,提高計算機效率。