Teorema do Restante Chinês e Solução de Equações Congruentes

Teorema do Restante Chinês e Solução de Equações Congruentes

Congruências são pilares na teoria dos números, com aplicações em áreas como criptografia. Este artigo explora o Teorema do Restante Chinês (CRT) e a resolução de equações congruentes, fornecendo implementações em C++ adaptadas para clareza e eficiência.

Fundamentos Teóricos

  • Pequeno Teorema de Fermat: Para primo p e inteiro a não divisível por p, ap-1 ≡ 1 (mod p).
  • Algoritmo Euclidiano Estendido: Calcula intieros x e y satisfazendo ax + by = gcd(a, b).
  • Inverso Multiplicativo: Dados a e m coprimos, existe x com ax ≡ 1 (mod m).
  • Teorema de Euler: Se a e n são coprimos, então aφ(n) ≡ 1 (mod n), onde φ é a função totiente.
  • Teorema do Restante Chinês: Resolve sistemas de congruências lineares simultâneas com módulos coprimos.

Problema 1: Determinação do Menor K via CRT

Dado um sistema de congruênccias K ≡ ai (mod mi), onde os mi são primos distintos, encontrar o menor inteiro positivo K que satisfza todas as condições.

Exemplo de Entrada:


3
2 1
3 2
5 3

Saída Esperada: 23

Especificação de Entrada:

  • Primeira linha: inteiro N (2 ≤ N ≤ 10) indicando o número de congruências.
  • Próximas N linhas: cada uma contém primo P e resto M (0 ≤ M < P).

Saída: O menor K < 109.

Implementação em C++

Utiliza o algoritmo euclidiano estendido para calcular inversos modulares no CRT.


#include <iostream>
#include <vector>
using namespace std;

typedef long long ll;

ll extended_gcd(ll a, ll b, ll& x, ll& y) {
    if (b == 0) {
        x = 1;
        y = 0;
        return a;
    }
    ll x1, y1;
    ll gcd = extended_gcd(b, a % b, x1, y1);
    x = y1;
    y = x1 - (a / b) * y1;
    return gcd;
}

ll solve_crt(int n, const vector<ll>& mods, const vector<ll>& rems) {
    ll prod = 1;
    for (ll m : mods) prod *= m;
    
    ll result = 0;
    for (int i = 0; i < n; ++i) {
        ll mi = mods[i];
        ll ri = rems[i];
        ll Mi = prod / mi;
        ll inv, dummy;
        extended_gcd(mi, Mi, inv, dummy);
        result = (result + ri * Mi * inv) % prod;
    }
    return (result + prod) % prod;
}

int main() {
    int n;
    cin >> n;
    vector<ll> mods(n), rems(n);
    for (int i = 0; i < n; ++i) {
        cin >> mods[i] >> rems[i];
    }
    cout << solve_crt(n, mods, rems) << endl;
    return 0;
}

Problema 2: Resolução da Equação Congruente ax ≡ 1 (mod b)

Encontrar o menor inteiro positivo x tal que ax ≡ 1 (mod b). Assume-se que a e b são coprimos.

Exemplo de Entrada:


3 10

Saída Esperada: 7

Especificação de Entrada:

  • Entrada: dois inteiros a e b (2 ≤ a, b ≤ 2×109).
  • Saída: o menor x positivo.

Implementação em C++

Aplica o algoritmo euclidiano estendido para calcular o inverso modular.


#include <iostream>
using namespace std;

typedef long long ll;

ll extended_gcd(ll a, ll b, ll& x, ll& y) {
    if (b == 0) {
        x = 1;
        y = 0;
        return a;
    }
    ll x1, y1;
    ll gcd = extended_gcd(b, a % b, x1, y1);
    x = y1;
    y = x1 - (a / b) * y1;
    return gcd;
}

ll modular_inverse(ll a, ll m) {
    ll x, y;
    ll g = extended_gcd(a, m, x, y);
    if (g != 1) {
        return -1; // Inverso não existe; problema garante solução.
    }
    return (x % m + m) % m;
}

int main() {
    ll a, b;
    cin >> a >> b;
    cout << modular_inverse(a, b) << endl;
    return 0;
}

Tags: congruência teorema do restante chinês algoritmo euclidiano estendido equações congruentes inverso modular

Publicado em 6-24 23:45