1. 程式人生 > >超級快速冪【費馬小定理】+【快速冪取模】

超級快速冪【費馬小定理】+【快速冪取模】



超級快速冪

Time Limit: 3000/1000 MS(Java/Others)Memory Limit:65536/65536 K (Java/Others)

Description

請計算:

a^(b^c)mod(1e9+7)

Input

多組資料,第一行為一個整數T,代表資料組數,接下來每行三個整數a,b,c1<=a,b,c<=1,000,000,000

Output

對於每組資料,輸出一行代表計算結果

Sample Input

2

1 2 3

2 3 2

Sample Output

1

512

解題思路:

首先,不能直接算a^(b^c % mod) % mod

正確的做法是根據費馬小定理,當a和mod互質時,有 a^(mod-1) % mod = 1

比如【對照例子理解程式碼更Easy哦】:

計算2^{100}除以13的餘數
2^{100} \equiv 2^{12 \times 8+4} \pmod{13}
\equiv (2^{12})^8 \cdot  2^4 \pmod{13}
\equiv 1^8 \cdot  16 \pmod{13}
\equiv 16 \pmod{13}
\equiv 3 \pmod{13}
//先給出快速冪模板
int power_mod(LL a, LL b, LL P)
{
    if(b == 0) return 1;
    LL ans = power_mod(a, b >> 1, P);
    ans = ans * ans % P;
    return (int)(b & 1) ? a % P * ans % P: ans;
}
//超級快速冪化簡的推導過程【對照例項理解】:
//div = (b^c) / (mod-1);
//rem = (b^c) % (mod-1);	// rem < mod

int rem = power_mod(b,c,mod-1);

//   a^(b^c) % mod
// = a^((mod-1)*div + rem) % mod
// = a^rem % mod

int ans = power_mod(a,rem,mod);
最後,發現原來超級快速冪也就是小case,是不是?微笑 Tips : 這個題其實是可以用尤拉函式,指數迴圈節做的,追根溯源,本質其實是一樣的,費馬小定理是尤拉函式的一個特例而已!!