所謂的快速冪,實際上是快速冪取模的縮寫
首先,最基本的辦法是:
int ans = 1;
for(int i=1;i<=b;i++)
ans =ans%c; //ans是對answer的縮寫
但是如果a很大,那麼a^b的結果就容易非常大,所以在求之前可以先對a做乙個變化 如下:
int ans = 1;
a =a%c; //加上這一句
for(int i=1;i<=b;i++)
ans =ans%c;
加上那一句之後,求出來的答案是不會變得,,可以舉個數字體味一下哦!
按照上面的思路,我們還可以在別的地方再取一次餘哦,讓過程中的數字盡可能地小:
int ans = 1;
a =a%c; //加上這一句
for(int i=1;i<=b;i++)
ans =ans%c;
噹噹噹噹~~~~~經過上面,我們終於可以用快速冪來求解了:
首先,快速冪的理論基礎:
快速冪的過程是快速求出a^b的過程,算到最後ans還是要%c的:
快速求出a^b:
1、當b為偶數時,a^b可以轉化為(a^2)的(b/2)次方
2、當b為奇數時,a^b可以轉化為(a^2)的(b/2)次方 再乘 a //比偶數多乙個乘a,可以放到最前面乘上
證明巴拉巴拉的我就不證了,可以帶個數字體會一下這個過程哦!
看**:
int ans = 1;
a =a%c; // a在此時%c是為了簡化數字
if(b%2==1) ans = (ans*a)%c; //如果是基數,要求多一步,可以提前算到ans中 ,這裡%c也是為了簡化數字
k=(a*a)%c; //取a^2 //k在此時%c是為了簡化數字
for(int i=1;i<=b/2;i++)
ans =ans %c; //在求出a^b的最後不要忘記%c哦
我們可以看到,我們把時間複雜度變成了o(b/2).當然,這樣子治標不治本。但我們可以看到,當我們令k = (a * a) mod c時,狀態已經發生了變化,我們把最終(a^b)%c轉化成了【(a^2)%c的b/2】%c,所以我們發現這個過程是可以迭代下去的。當然,對於奇數的情形會多出一項乘a的過程 ,這裡像上面一樣加在開始的地方ans = (ans * a) % c;就可以了。形如上式的迭代下去後,當b=0時,所有的因子都已經相乘,演算法結束。於是便可以在o(log b)的時間內完成了。於是,有了最終的演算法:快速冪演算法。
int ans =1;
a=a%c;
while(b>0) //這裡我不太懂哎,,最後為什麼沒有在%c 但是既然是乙個簡化的過程,過程中應該已經省的很多了吧
把上面的**結構化,也就是寫成函式
int powermod(int a,int b,int c)
return ans;
}
本演算法的時間複雜度為o(logb),能在幾乎所有的程式設計(競賽)過程中通過,是目前最常用的演算法之一。
擴充套件:有關於快速冪的演算法的推導,還可以從另乙個角度來想。
=? 求解這個問題,我們也可以從進製轉換來考慮:
將10進製的b轉化成2進製的表示式:
那麼,實際上,.
所以注意此處的要麼為0,要麼為1,如果某一項,那麼這一項就是1,這個對應了上面演算法過程中b是偶數的情況,為1對應了b是奇數的情況[不要搞反了,讀者自己好好分析,可以聯絡10進製轉2進製的方法],我們從依次乘到。對於每一項的計算,計算後一項的結果時用前一項的結果的平方取餘。對於要求的結果而言,為時ans不用把它乘起來,[因為這一項值為1],為1項時要乘以此項再取餘。這個演算法和上面的演算法在本質上是一樣的,讀者可以自行分析,這裡我說不多說了,希望本文有助於讀者掌握快速冪演算法的知識點,當然,要真正的掌握,不多練習是不行的。
快速冪問題
求冪方法 pow函式 也就是平常使用pow函式,最簡單的實現就是一直累乘,可以得到這樣的 123 4567 int pow int a,int n return ans 快速冪取模 根據同餘定理,我們知道 ab m a m b m m 其實快速冪取模也是用到這個定理,那麼根據上面的定理可以推導出另乙...
快速冪問題
求a b mod p 首先讓計算機求出a b,如果直接暴力的話,計算機要計算b次,但是b的資料範圍太大,直接計算可能會超時,所以要採用快速冪,將複雜度降為o log b 這樣表示之後,我們就可以在快速冪的過程中讓a不斷的自乘 看下 ll power int a,int b,int p return ...
快速冪問題
求 a 的 b 次方對 p 取模的值。輸入格式 三個整數 a,b,p 在同一行用空格隔開。輸出格式 輸出乙個整數,表示a b mod p的值。資料範圍 0 a,b,p 109 資料保證 p 0 輸入樣例 3 2 7輸出樣例 2快速冪思想 如果我們想求37是多少,用最暴力的做法只需要迴圈進行7次相乘,...