1. 程式人生 > >簡單易懂的快速冪取模演算法

簡單易懂的快速冪取模演算法

本文是上一篇文章《程式設計師必學:快速冪演算法》的續集,上一篇文章詳細地介紹了快速冪演算法,提供了遞迴、非遞迴的2種實現方案

丟擲問題

請設計一個演算法求x的y次冪模z的結果:(x ^ y) % z

  • x、y、z都是整數
  • z ≠ 0, y ≥ 0
  • x、y的絕對值可能很大,比如(1234 ^ 4567) % 30

思考

由於x、y的絕對值可能很大,x ^ y的結果可能會溢位。所以先求x ^ y,再對z取模,顯然是不現實的。

這裡要藉助模運算的一條運算規則

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

根據上面的推導,就可以很容易寫出程式碼實現

遞迴實現

int powMod(int x, int y, int z) {
    if (y == 0) return 1 % z;
    int half = powMod(x, y >> 1, z);
    half = (half * half) % z;
    if ((y & 1) == 0) { // y是偶數
        return half;
    } else { // y是奇數
        return (half * (x % z)) % z;
    }
}

非遞迴實現

int powMod(int x, int y, int z) {
    int result = 1 % z;
    x %= z;
    while (y != 0) {
        if ((y & 1) == 1) {
            result = (result * x) % z;
        }
        x = (x * x) % z;
        y >>= 1;
    }
    return result;
}

測試用例

// 4
powMod(1234, 4567, 30);
// 699
powMod(123, 456, 789);
}

如果你特別希望我寫點什麼方面的內容,也可以留言建議,謝謝。歡迎關注

相關推薦

簡單易懂快速演算法

本文是上一篇文章《程式設計師必學:快速冪演算法》的續集,上一篇文章詳細地介紹了快速冪演算法,提供了遞迴、非遞迴的2種實現方案 丟擲問題 請設計一個演算法求x的y次冪模z的結果:(x ^ y) % z x、y、z都是整數 z ≠ 0, y ≥ 0 x、y的絕對值可能很大,比如(1234 ^ 4567) %

快速()演算法

對於普通型別的求a^n,我們的求法是不是a*a*a*a....,這樣乘以n次,時間複雜度為O(n),對於普通n比較小的我們可以接受,然而當n比較大的時候,計算就慢了,所以我們就去尋找更快捷的計算方法! 例如:我們要求2^8,我們通過當為偶數的時候,a^n=(a*a)^(n/

轉載ACM 快速演算法詳解

快速冪取模的用途:在ACM這類競賽中,可能會遇到指數型的資料取模問題,這個時候如果直接用int或者long long儲存,就 有可能會超出計算機整數的存取範圍,而導致資料出錯。所以我們需要一種方法進行計算。而這種方法就是我們這次要講到 的快速冪取模(簡稱快速冪)。這種演算法在時間和空間上都做了儘可能的優化

快速演算法小結

快速冪取模演算法,是比較常見的演算法。分享給大家供大家參考之用。具體如下: 首先,所謂的快速冪,實際上是快速冪取模的縮寫,簡單的說,就是快速的求一個冪式的模(餘)。在程式設計過程中,經常要去求一些大數對於某個數的餘數,為了得到更快、計算範圍更大的演算法,產生了快速冪取模

快速演算法

演算法2:另一種演算法利用了二分的思想,可以達到O(logn)。可以把b按二進位制展開為:b = p(n)*2^n  +  p(n-1)*2^(n-1)  +…+   p(1)*2  +  p(0) 其中p(i) (0<=i<=n)為 0 或 1 這樣 a^b =  a^ (p(n)*2^n 

演算法競賽寶典 分治演算法 快速運算

//理解快速冪運算即可,類似於加法//理解快速冪運算即可,類似於加法 #include<iostream> #include<algorithm> #include<bi

快速快速演算法超級詳細介紹

        今天在網上看了一些快速冪取模演算法的介紹,總體感覺要麼文章介紹的很簡略,導致我搞了半天才搞明白什麼意思,還有的文章直接放上了錯誤的程式碼,真是坑爹啊!所以我就特意寫一篇文章方便大家理解一下這個演算法的原理和程式碼是什麼意思。原理介紹:     目標:快速求出 

快速和快乘

要去 ont pow 取模 當下 tex str 過程 return 一、快速冪取模概念   快速冪取模,顧名思義,就是快速的求一個冪式的模(余),比如a^b%c,快速的計算出這個式子的值。   在程序設計過程中,經常要去求一些大數對於某個數的余數,為了得到更快、計算範圍更

【模板】快速

模板 space 變量 pac esp const def class cstring 快速冪取模的模板,要註意所有變量都要開成long long類型的防溢出: #include<cstdio> #include<algorithm>

POJ 3233-Matrix Power Series( S = A + A^2 + A^3 + … + A^k 矩陣快速)

spa nta plm lines case arch lang stream 矩陣 Matrix Power Series Time Limit: 3000MS Memory Limit: 131072K Total Submissions: 20309

快速ADT

col 復雜度 mod 狀態 log post while color ret int pow_mod(int a, int n, int m){ if(n==0) return 1; int x=pow_mod(a, n/2, m); long

快速(當數很大時,相乘long long也會超出的解決辦法)

結合 超出 但是 long 數字 也會 連續 return result 當幾個數連續乘最後取模時,可以將每個數字先取模,最後再取模,即%對於*具有結合律。但是如果當用來取模的數本身就很大,采取上述方法就不行了。這個時候可以借鑒快速冪取模的方法,來達到大數相乘取模的效果。

快速算法

val range 引入 fast fine eva wid 假設 占用 1.大數模冪運算的缺陷: 快速冪取模算法的引入是從大數的小數取模的樸素算法的局限性所提出的,在樸素的方法中我們計算一個數比如5^1003%31是非常消耗我們的計算資源的,在整個計算過程中最麻煩的就是

快速

typedef ret () str pre namespace amp mes pri #include<iostream> #include<cstdio> #include<cmath> #include<cstring&g

【費馬小定理+快速】ACM-ICPC 2018 焦作賽區網絡預賽 G. Give Candies

print using pri long long ger ssi bit one ive G. Give Candies There are N children in kindergarten. Miss Li bought them N candies. To mak

快速快速

它的 signed 1.5 原來 現在 轉化 mil ram 自己 首先,快速冪的目的就是做到快速求冪,假設我們要求a^b,按照樸素算法就是把a連乘b次,這樣一來時間復雜度是O(b)也即是O(n)級別,快速冪能做到O(logn),快了好多好多。它的原理如下:   假設我們要

Hdu 2685 I won't tell you this is about number theory 快速+gcd

Problem Description To think of a beautiful problem description is so hard for me that let's just drop them off. :) Given four integers a,m,n,k,and

快速的計算複雜度

背景:RSA加密演算法: 的計算複雜度 計算原理及步驟 ,故將M縮小至n的餘數範圍內 (最核心的思想) 不斷的將變為,舉個例子:,這樣的話每一次就只需要計算,每一步省一半的計算量 但如果某一步的是奇數,就把它直接算到裡面 從第二步可以看出,演算法的複雜度是

POJ 1995 Raising Modulo Numbers(快速)

POJ1995 題目大意 有N個人,每個人給出兩個數字a,b,求∑(Ai\^Bi) mod M。 Input 3 16 4 2 3 3 4 4 5 5 6 36123 1 2374859 3029382 17 1 3 18132 Output

hdu2065"紅色病毒"問題(指數母函式+快速)

"紅色病毒"問題 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 9329