C語言實現快速冪的遞迴與迭代求解

2021-09-25 00:17:05 字數 1533 閱讀 5345

1. 問題描述:

給定三個正整數a,b(a < 10 ^ 9,b < 10 ^ 18,1 < m < 10 ^ 9)求解出a ^ b % m

2. 思路分析:

① 對於上面這個問題,最簡單的思路是使用乙個迴圈來進行累乘,直到累乘的次數等於了b那麼迴圈就結束了,但是假如按照這樣的思路來解決,對於o(b)的時間複雜度為o(10 ^ 8)都比較難支援了,更何況是10 ^ 18呢?所以上面的解法是不行的

② 這裡需要使用到快速冪的計算,首先我們可以使用遞迴的方法來進行求解,下面是求解的式子:

1)如果b是奇數,那麼有 a ^ b = a * a ^ (b - 1);

2)如若b是偶數,那麼有a ^ b = a ^ (b / 2) * a ^ (b / 2);

從上面的式子我們可以知道對於b是奇數的情況下是能夠轉化為偶數的,而b是偶數的情況下我們是可以先轉換為b / 2的情況,在經過若干次的轉換之後那麼最後到達了遞迴的邊界就是b變成了0的情況,這個時候我們直接返回1就可以了,a ^ 0 = 1

③ 比如要求解出 2 ^ 10,我們需要經過下面的步驟:

1)由10是偶數因此先要求解 2 ^ 5,然後2 ^ 10 = 2 ^ 5 * 2 ^ 5;

2)對於2 ^ 5來說,5是奇數,所以先要求解出2 ^ 4,2 ^ 5 = 2 * (2 ^ 4)

3)對於2 ^ 4來說,4是偶數,所以先要求解出2 ^ 2,2 ^ 4 = 2 ^ 2 * 2 ^ 2

4)對於2 ^ 2來說,2是偶數,所以先要求解出2 ^ 1,2 ^ 2 = 2 ^ 1 * 2 ^ 1

5)對於2 ^ 0來說,1是奇數,所以先要求解出2 ^ 0,2 ^ 1 = 2 * 2 ^ 0

6)2 ^ 0 = 1遞迴結束

3. 下面是具體的**:

#includetypedef long long ll;

ll binarypow(ll a, ll b, ll m)

} int main(void)

4.  除了上面的遞迴求解的方法之外,我們還可以使用遞推的方法來進行求解,思路分析如下:

① 首先比如我們需要求解出2 ^ 10,10的二進位制形式為1010,所以2 ^ 10 = 2 ^ 8 * 2 * 2得到,而8,2對應的是10這個冪的二進位制位上是否是1,,這樣我們使用遞推的思路就比較清晰了,下面是具體的步驟:

1)初始的時候可以令ans = 1

2)判斷b的二進位制位數是否是1,使用b & 1 == 1來進行判斷,b & 1進行位與操作這樣比 b % 2 == 1來判斷的執行速度會更快

3)令a平方,並且b後移1位相當於是b /= 2

4)只要是b大於0那麼就回到2)

5. 下面是具體的**:

#includetypedef long long ll;

ll binarypow(ll a, ll b, ll m)

a = a * a % m;

//b除以2

b >>= 1;

} return ans;

} int main(void)

快速冪(C語言實現) 超詳細

快速冪演算法 所謂的快速冪,實際上是快速冪取模的縮寫,簡單的說,就是快速的求乙個冪式的模 餘 在程式設計過程中,經常要去求一些大數對於某個數的餘數,為了得到更快 計算範圍更大的演算法,產生了快速冪取模演算法。我們先從簡單的例子入手 求 幾。演算法1.首先直接地來設計這個演算法 int ans 1 f...

C 不用遞迴,寫出快速求冪的程式

剛解完2.15這道題 c 證明x的62次方可以只用8次乘法算出 往下看就發現了這個,直接貼上我解2.15這道題的時候的出現的一種解法就行了,而且演算法恰好滿足2.16和2.17的要求。程式如下 used用來累計使用乘法的次數 include include define number 2 defin...

c語言快速排序 遞迴與非遞迴實現

遞迴 1 先在待排序序列中選擇乙個基準資料,一般常用的就是第乙個資料 2 i,j i從前向後 j從後向前 當i j時,進入迴圈 1 從後向前找第乙個比基準小的資料 i 在start位置 end位置 和中間位置找到中位數,將其換到start位置 void getmodnum int arr,int s...