求a^k % p,(1 <= a, k, p <=10^9)
#include <iostream> #include <algorithm> using namespace std; typedef long long LL; LL qmi(int a, int b, int p) { LL res = 1; while(b) { if(b & 1) res = res * a % p; b >>= 1; a = (LL)a * a % p; } return res; } int main() { int n; cin>>n; while(n--) { int a,b,p; cin>>a>>b>>p; cout<<qmi(a,b,p)<<endl; } }
If you use violence, it is O (n) = 10 ^ 9, and the fast power is logn level, log10 ^ 9 = 30;
The principle is: for example, 4 ^ 5 = 4 ^ 2 ^ 0 + 4 ^ 2 ^ 2,
The first step is to generate 4 ^ 2 ^ 0 = 4 mod 10;
The second step generates 4 ^ 2 ^ 1 = 6 mod 10;
The third step is to give birth 4 ^ 2 ^ 2 = 6 mod 10;
You can see that each step is the square of the front, so the fast is the same. At the beginning, the base a = a, a = a * a = a ^ 2, a = a ^ 2 * a ^ 2 = a ^ 4, a = a ^ 4 * a ^ 4 = a ^ 8;
If there is 1, then (a & 1) res = res * a; a >> = 1; a = a * a% p;
Note: I will always forget the condition if (a & 1). 4 ^ 101, res = 4, res = 4 * 4 ^ 4 = 4 ^ 5; so the exponent looks like a sum, but when added to the bottom, it is continuously squared and then multiplied by the previous product.
res = 1;if(a & 1) res = res * a % p; a >>= 1; a = a * a;
Congruence inverse:
a / b congruence a * x mod m
b * x congruence 1 mod m
Fermat's theorem: b and p are relatively prime, then b ^ p-1 is congruent p. (Eg 2 ^ (3-1) = 4% 3 = 1, 2 ^ (5-1) = 16% 5 = 1, 5 ^ (3-1) = 25% 3 = 1, 3 ^ (5-1 ) = 81% 5 = 1)
b * b ^ p-2 congruence p
Then the multiplicative inverse of b% p is b ^ p-2. (If the remainder of b and p is not 0, then there must be no inverse element) (If b and p are relatively prime, then there must be an inverse element b ^ (p-2) by Fermat's theorem, because both prime numbers are> = 2.
So you can use fast power to find:
#include <iostream> #include <algorithm> #include <cstdio> typedef long long LL; using namespace std; int qmi(int a, int p, int k) { int res = 1; while(p) { if(p & 1)res = (LL)res * a % k; p >>= 1; a = (LL)a * a % k; } return res; } int main() { int n; scanf("%d",&n); while(n--) { int a,p; scanf("%d%d",&a,&p); int res = qmi(a, p - 2, p); if(a % p) printf("%d\n",res); else printf("impossible\n"); } }
int res = qmi (a, p-2 , p);
if (a% p) printf ("% d \ n" , res);
Note that you cannot judge whether the result returned by res is 0 or 1 because if a = 2, p = 2, it is equal to 1, so it depends on whether a and p are not composite.