使用大指數計算(a^b)%MOD
在此編碼挑戰中,任務是計算pow( a, b) %MOD,其中指數b 可能非常大。雖然傳統的 log(b) 時間複雜度方法適用於較小的值,但當 b 超過 C 中 long long 資料類型的容量時,它就變得不切實際。
然而,更有效的方法涉及利用 Euler 的 totient 函數, φ(MOD)。歐拉定理指出 a^φ(MOD)≡1(mod MOD)。這意味著 a 的冪可以顯著降低為 a^(b % φ(MOD))。
計算 φ(MOD) 本身就是一項不平凡的任務,但可以用整數分解法來實現。計算完成後,指數 b 可以替換為 b % φ(MOD),以顯著減少計算時間。
進一步改進
進一步改進2008 年,Schramm 證明φ (b) 可以透過gcd(b, i) 的離散傅立葉變換獲得,其中i 的範圍為1 到b。這消除了顯式因式分解的需要。 此外,Carmichael 函數 λ(MOD) 可用於獲得正確答案,特別是當 a 和 MOD 共享公因數時。
程式碼實作#include
#include
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) { return (b == 0) ? a : gcd(b, a % b); }
ll pmod(ll a, ll b, ll mod) {
if (b == 0) return 1;
if (b % 2 == 1) {
return (a * pmod(a, b - 1, mod)) % mod;
} else {
ll tmp = pmod(a, b / 2, mod);
return (tmp * tmp) % mod;
}
}
int main() {
ll a, b, mod;
cin >> a >> b >> mod;
cout 以下程式碼片段作為 C 語言的範例:#include
#include
使用命名空間 std;
typedef 長長 ll;
ll gcd(ll a, ll b) { return (b == 0) ? a : gcd(b, a % b); }
ll pmod(ll a, ll b, ll mod) {
如果(b==0)返回1;
如果(b%2==1){
返回 (a * pmod(a, b - 1, mod)) % mod;
} 別的 {
ll tmp = pmod(a, b / 2, mod);
返回 (tmp * tmp) % mod;
}
}
int main() {
ll a、b、mod;
cin >> a >> b >> mod;
cout
免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。
Copyright© 2022 湘ICP备2022001581号-3