1. 程式人生 > 其它 >【數論】快速冪

【數論】快速冪

$對於a^{b} ,可以用O(logb)的時間複雜度求出,使用二進位制拆分的思想將b拆分成二進位制,分別得出a^{2^{0}},a^{2^{1}}...a^{2^{n}}之後求積即可。$

 1 #include <iostream>
 2 using namespace std;
 3 
 4 long long qmi(int a,int b,int p)
 5 {
 6     long long res = 1,base = a;
 7     while(b)
 8     {
 9         if(b & 1)
10             res = res * base
% p; 11 base = base * base % p; 12 b >>= 1; 13 } 14 return res; 15 } 16 17 int main() 18 { 19 int n; 20 cin >> n; 21 while(n--) 22 { 23 int a,b,p; 24 cin >> a >> b >> p; 25 cout << qmi(a,b,p) << endl;
26 } 27 return 0; 28 }

快速冪求逆元

乘法逆元的定義

$若整數b,m互質,並且對於任意的整數a,如果滿足b|a,則存在一個整數x,使得a\div b \equiv a\times x(mod m),則稱x為b的模m乘法逆元,記為b^{-1}(mod m).b存在乘法逆元的充要條件就是b與模數m互質。當模數m為質數時,b^{m-2}即為b的乘法逆元。$

為了方便,我們直接假設m就是質數,便可以使用快速冪直接求出$b^{m-2}$。

 1 #include <iostream>
 2 using namespace std;
 3 
 4 long
long qmi(int a,int b,int p) 5 { 6 long long res = 1,base = a; 7 while(b) 8 { 9 if(b & 1) 10 res = res * base % p; 11 base = base * base %p; 12 b >>= 1; 13 } 14 return res; 15 } 16 17 int main() 18 { 19 int n; 20 cin >> n; 21 while(n--) 22 { 23 int a,p; 24 cin >> a >> p; 25 if(a % p == 0) 26 cout << "impossible" << endl; 27 else 28 cout << qmi(a,p - 2,p) << endl; 29 } 30 return 0; 31 }