Invers modular
Problema
În cadrul multor probleme de informatică se cere calcularea unei valori și afișarea acesteia modulo unei constante precizate în enunț. Se poate observa faptul că operațiile de adunare, scădere și înmulțire se pot efectua fără probleme cu respect la un anumit modul, însă operația de împărțire trebuie tratată diferit. Mai exact, dacă , si sunt numere întregi, , , egalitatea nu este întotdeauna adevărată.
Se recomandă citirea informațiilor din articolul despre matematică de bază înainte de a citi noțiunile de aici.
Ce este inversul modular?
În matematică, inversul unui număr real este acel număr care satisface . Împărțirea unui număr la este echivalentă cu înmulțirea acestuia cu . Tot așa, și în aritmetica modulară definim inversul modular al unui număr (cu respect la modulul ) acel număr notat care satisface relația . Se poate demonstra faptul că un număr întreg are un invers modular modulo dacă și numai dacă el și sunt prime între ele.
Atunci, pentru a efectua operația de împărțire cu respect la modul dintre și trebuie să îl înmulțim pe cu inversul modular al lui , deoarece .
Cum calculăm inversul modular al unui număr?
Calcularea folosind mica teoremă a lui Fermat
Definiție
Dacă este un număr prim și este un număr întreg prim cu , atunci .
Congruența se mai poate scrie ca:
Se poate observa ușor că de fapt inversul modular al lui este , care poate fi calculat rapid folosind exponențierea logaritmică.
Algoritmul extins al lui Euclid
Luăm în considerare următoarea identitate:
Identitatea lui Bézout
Fie numerele întregi , și . Atunci, există cel puțin o pereche de numere întregi și astfel încat .
Daca și sunt prime între ele, atunci există și astfel încât . De aici reiese faptul că , adică este inversul modular al lui .
Fie câtul împărțirii lui la și restul. Algoritmul lui Euclid ne spune că . Astfel, există și care satisfac .
Dar
Se observa că și , iar . Astfel, putem folosi recursiv algoritmul lui Euclid, adăugându-i parametrii și :
void euclidExtins(const int a, const int b, int &x1, int &y1);În cazul în care parametrul din funcție este egal cu 0, atunci va fi egal cu 1 și astfel vom seta , iar poate lua orice valoare, de exemplu tot 1.
Atenție
Valoarea lui poate fi și negativă. Dacă este necesară o valoare pozitivă atunci facem operația .
Mai jos se poate observa o implementare în C++ a algoritmului lui Euclid, respectiv a funcției de calculare a inversului modular al lui pentru modulul :
void euclidExtins(const int a, const int b, int &x1, int &y1) {
if (b == 0) {
x1 = 1;
y1 = 1;
return;
}
int x2, y2;
euclidExtins(b, a % b, x2, y2);
x1 = y2;
y1 = (x2 - a / b * y2) % M;
}
int inversModular(const int A) {
int x1, y1;
euclidExtins(A, M, x1, y1);
/* daca vrem x1 pozitiv
if(x1 < 0)
x1 += M;
*/
return x1;
}Probleme cu invers modular
- Invers Modular
- Lot 2021 Juniori Prosum
- Codeforces Beautiful Numbers
- Toate aplicatiile prezentate la combinatorica
- Codeforces Sum of the kth powers
Lectură suplimentară
- Algoritmul lui Euclid extins. Invers modular - Pbinfo
- Modular arithmetic - USACO Guide
- Modular multiplicative inverse
- Calculate modulo inverses efficiently
- Modular arithmetic for Beginners - Codeforces
- Funcție scurtă de a calcula inversul modular - Codeforces
- Modular Inverse / Inverse Remainder / Modular Division – A Quick Guide - Codeforeces