打工人必會的快速冪演算法詳解

2022-06-25 15:00:11 字數 3996 閱讀 5854

快速冪是什麼?

有多快?

用的多麼?

下面來詳細看看快速冪演算法吧!

先看個問題再說:

首先問你乙個問題,如果讓你求(2^10)%1000你可能會這樣寫:

int va=1;

for(int i=0;i<10;i++)

system.out.println(va%10000);

熟悉的1024沒問題,總共計算了10次。但是如果讓你算(2^50)%10000呢?

你可能會竊喜,小樣,這就想難住我?我知道int只有32位,50位超出範圍會帶來數值越界的異常,我這次可以用long,long有64位呢!

long va=1;

for(int i=0;i<50;i++)

system.out.println(va);

system.out.println(va%10000);

(a + b) % p = (a % p + b % p) % p  (1)

(a - b) % p = (a % p - b % p ) % p (2)

(a * b) % p = (a % p * b % p) % p (3)

a ^ b % p = ((a % p)^b) % p (4)

你還算聰明一眼發現其中的規律:

(a * b) % p = (a % p * b % p) % p   (3)

(2*2*2···*2) %1e10=[2*(2*2···*2)]%1e5=(2%1e5)*(2*2···*2%le5)%1e5

憑藉這個遞推你明白:每次相乘都取模。機智的你pia pia寫下以下**,卻發現另乙個問題:怎麼跑不出來?

咱們打工人需要對計算機執行速度和數值有乙個大致的概念。迴圈體中不同操作占用時間不同,所以當你的程式迴圈次數到達1e6或1e7的時候就需要非常非常小心了。如果迴圈體邏輯或者運算較多可能非常非常慢。

機智的你不甘失敗,開始研究其數的規律,將這個公式寫在手上、膀子上、小紙條上。吃飯睡覺都在看:

然後你突然發現其中的奧秘,n次冪可以拆分成乙個平方計算後就剩餘n/2的次冪了:

現在你已經明白了快速冪是怎麼回事,但你可能有點上頭,還是給我講了很多內容:

至於快速冪已經懂了,我們該怎麼實現這個演算法呢?

2*2*2*2*2=2 * (2*2*2*2) 奇數問題可以轉化為偶數問題。
這裡,遞迴的解法如下

long c=10000007;

public long divide(long a, long b)

非遞迴實現也不難,控制好迴圈條件即可:

//求 a^b%1000000007

long c = 1000000007;

public long divide(long a, long b)

return res;

}

對於非遞迴你可能有點模糊為啥偶數情況不給res賦值。這裡有兩點:

如果還是不懂,可以用這個圖來解釋一下:

你以為這就結束了?雖然快速冪主要內容就是以上內容,但是總有很多牛人能夠發現很有趣的規律—矩陣快速冪。如果你沒聽過的話建議仔細看看了解一下。

前幾個斐波那契的數列為:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, …

斐波那契從遞推式就可以看出是指數級別的增長,所以稍微多幾個數字就是**式增長,所以很多時候也會要求最後幾位的結果。有了前面模運算公式溢位就不成問題,但n如果非常非常大怎麼快速計算就成了乙個新的問題。

我們看下面一組公式:

f(n+1) = f(n)   + f(n-1)

f(n) = f(n)

如果那f(n)和f(n-1)放到乙個矩陣中(一行兩列):[f(n+1),f(n)]能否找到和[f(n),f(n-1)]之間的什麼規律呢?

答案是存在規律的,看上面的公式知道

[f(n+1),f(n)]

=[f(n)+f(n-1),f(n)]

[1 1]

=[f(n),f(n-1)] *

[1 0]

[1 1] [1 1]

=[f(n-1),f(n-2)]* *

[1 0] [1 1]

=·······

所以現在你可以知道它的規律了吧,這樣一直迭代到f(2),f(1)剛好都為1,所以這個斐波那契的計算為:

而這個矩陣有很多次冪,就可以使用快速冪啦,原理一致,你只需要寫乙個矩陣乘法就可以啦,下面提供乙個矩陣快速冪求斐波那契第n項的後三位數的模板,可以拿這個去試一試poj3070的題目啦。

public int fibonacci(int n)

,};//進行快速冪的矩陣

int b=,};//儲存漏單奇數、結果的矩陣,初始為單位矩陣

int time=0;

while(n>0)

a=matrixmultiplication(a, a);

n/=2;

}return b[0][0];

}public int matrixmultiplication(int a,int b){//

int x=a.length;//a[0].length=b.length 為滿足條件

int y=b[0].length;//確定每一排有幾個

int c=new int [x][y];

for(int i=0;i這篇到這裡就肝完啦,其實快速冪的內容還不止這麼多,尤其是矩陣快速冪,會有著各種巧妙的變形,不過跟數學有一些關係,這年頭,不會點演算法、不會點數學真的是舉步維艱。所以大家要對本篇內容好好吸收,讓我那麼久的努力發揮出作用。

關注bigsai,回覆bigsai領取乾貨資源,下次再見,打工人!

演算法提高快速冪(快速冪演算法詳解)

問題描述 給定a,b,p,求 a b mod p。輸入格式 輸入共一行。第一行有三個數,n,m,p。輸出格式 輸出共一行,表示所求。樣例輸入 2 5 3 樣例輸出 資料規模和約定 共10組資料 對100 的資料,a,b為long long範圍內的非負整數,p為int內的非負整數。所謂的快速冪,實際上...

快速冪演算法詳解

快速冪 intpow int a,int b return ans 常規求冪運算 ll pow ll a,ll b 快速冪這個東西比較好理解,理解過後會發現非常的巧妙。快速冪的目的就是做到快速求冪,假設我們要求a b,按照樸素演算法就是把a連乘b次,這樣一來時間複雜度是o b 也即是o n 級別,快...

最詳解易懂的快速冪演算法

快速冪取模演算法 在 上一直沒有找到有關於快速冪演算法的乙個詳細的描述和解釋,這裡,我給出快速冪演算法的完整解釋,用的是c語言,不同語言的讀者只好換個位啦,畢竟讀c的人較多 所謂的快速冪,實際上是快速冪取模的縮寫,簡單的說,就是快速的求乙個冪式的模 餘 在程式設計過程中,經常要去求一些大數對於某個數...