Puissance rapide et élément inverse

求 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 ;
    tandis que (b) 
    { 
        if (b & 1 ) res = res * a% p; 
        b >> = 1 ; 
        a = (LL) a * a% p; 
    } 
    return res; 
} 
int main () 
{ 
    int n; 
    cin>> n;
    tandis que (n-- ) 
    { 
        int a, b, p; 
        cin >> a >> b >> p; 
        cout << qmi (a, b, p) << endl; 
    } 
}

Si vous utilisez la violence, c'est O (n) = 10 ^ 9, et la puissance rapide est au niveau logn, log10 ^ 9 = 30;

Le principe est: par exemple, 4 ^ 5 = 4 ^ 2 ^ 0 + 4 ^ 2 ^ 2,

La première étape consiste à générer 4 ^ 2 ^ 0 = 4 mod 10;

La deuxième étape génère 4 ^ 2 ^ 1 = 6 mod 10;

La troisième étape consiste à donner naissance à 4 ^ 2 ^ 2 = 6 mod 10;

Vous pouvez voir que chaque pas est le carré du devant, donc le jeûne est le même. Au début, la base a = a, a = a * a = a ^ 2, a = a ^ 2 * a ^ 2 = a ^ 4, a = a ^ 4 * a ^ 4 = a ^ 8;

S'il y a 1, alors (a & 1) res = res * a; a >> = 1; a = a * a% p;

Remarque: J'oublierai toujours la condition si (a & 1). 4 ^ 101, res = 4, res = 4 * 4 ^ 4 = 4 ^ 5; l'exposant ressemble donc à une somme, mais lorsqu'il est ajouté au fond, il est continuellement carré et multiplié par le produit précédent.

res = 1; if (a & 1) res = res * a% p; a >> = 1; a = a * a;

Congruence inverse:

congruence a / b a * x mod m 

b * x congruence 1 mod m

Théorème de Fermat: b et p sont relativement premiers, alors b ^ p-1 est congru p. (Par exemple 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

Alors l'inverse multiplicatif de b% p est b ^ p-2. (Si le reste de b et p n'est pas 0, alors il ne doit pas y avoir d'élément inverse) (Si b et p sont relativement premiers, alors il doit y avoir un élément inverse b ^ (p-2) par le théorème de Fermat, car les deux nombres premiers sont> = 2.

Vous pouvez donc utiliser une alimentation rapide pour trouver:

#include <iostream> 
#include <algorithm> 
#include <cstdio> 
typedef long  long LL;
using  namespace std;
int qmi ( int a, int p, int k) 
{ 
    int res = 1 ;
    tandis que (p) 
    { 
        if (p & 1 ) res = (LL) res * a% k; 
        p >> = 1 ; 
        a = (LL) a * a% k; 
    } 
    return res; 
} 
intmain () 
{ 
    int n; 
    scanf ( " % d " , & n);
    tandis que (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); 
Notez que vous ne pouvez pas juger si le résultat renvoyé par res est 0 ou 1 car si un = 2, p = 2, il est égal à 1, donc cela dépend si a et p ne sont pas composites.

Je suppose que tu aimes

Origine www.cnblogs.com/longxue1991/p/12725394.html
conseillé
Classement