Fast power and inverse element

求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.

Guess you like

Origin www.cnblogs.com/longxue1991/p/12725394.html