Teorema Chinês do Resto Estendido em C++ para Sistemas de Congruências

O Teorema Chinês do Resto Estendido (ExCRT) resolve sistemas de congruências da forma \(x \equiv r_i \pmod{m_i}\) para \(i=1,\ldots,k\), mesmo quando os módulos \(m_i\) não são coprimos entre si. A abordagem baseia-se na combinação iterativa de equações usando o algoritmo de Euclides estendido.

Fundamentos do Algoritmo de Euclides Estendido

Para resolver a equação diofantina linear \(a \cdot x + b \cdot y = \gcd(a, b)\), onde \(a\) e \(b\) são inteiros, o algoritmo de Euclides estendido fornece uma solução particular. Implementado recursivamente, ele calcula simultaneamente o máximo divisor comum (MDC) e os coeficientes \(x\) e \(y\).

typedef long long LL;

LL euclides_estendido(LL a, LL b, LL &x, LL &y) {
    if (b == 0) {
        x = 1;
        y = 0;
        return a;
    }
    LL x_prox, y_prox;
    LL mdc = euclides_estendido(b, a % b, x_prox, y_prox);
    x = y_prox;
    y = x_prox - (a / b) * y_prox;
    return mdc;
}

Esta função retorna o MDC de \(a\) e \(b\), e armazena em \(x\) e \(y\) uma solução particular. Para resolver \(a \cdot x + b \cdot y = c\), onde \(c\) é um inteiro, é necessário que \(c\) seja divisível pelo MDC. Caso contrário, não existe solução.

Demonstração da Combinação de Congruências

Considere o caso com duas congruências: \(x \equiv r_1 \pmod{m_1}\) e \(x \equiv r_2 \pmod{m_2}\). Isso é equivalente a \(x = k_1 m_1 + r_1 = k_2 m_2 + r_2\) para inteiros \(k_1\) e \(k_2\). Reorganizando, obtemos a equação diofantina:

\[k_1 m_1 - k_2 m_2 = r_2 - r_1.\]

Aplicando o algoritmo de Euclides estendido para resolver \(k_1' m_1 - k_2' m_2 = \gcd(m_1, m_2)\), multiplicamos ambos os lados por \((r_2 - r_1)/\gcd(m_1, m_2)\) para obter uma solução particular \(k_1\). Substituindo em \(x = k_1 m_1 + r_1\), encontramos uma solução particular \(x_0\). A solução geral é então \(x = x_0 + t \cdot \text{mmc}(m_1, m_2)\), onde \(t\) é um inteiro arbitrário e \(\text{mmc}\) é o mínimo múltiplo comum. Isso produz uma nova congruência equivaelnte: \(x \equiv x_0 \pmod{\text{mmc}(m_1, m_2)}\). O processo é repetido iterativamente para todas as congruências do sistema, resultando em uma única congruência \(x \equiv R \pmod{M}\), onde \(M\) é o MMC de todos os módulos.

Implementação em C++

A função abaixo implementa o ExCRT. Ela mantém um módulo acumulado \(M\) e um resto acumulado \(R\), combinando cada congruência sequencialmente. Se em algum passo a congruência for inconsistente, a função retorna -1 indicando falta de solução.

#include <vector>
using namespace std;
typedef long long LL;

LL resolver_ex_crt(const vector<LL>& restos, const vector<LL>& modulos) {
    LL mod_corrente = modulos[0];
    LL resto_corrente = restos[0];
    int n = modulos.size();
    
    for (int i = 1; i < n; i++) {
        LL x, y;
        LL mdc = euclides_estendido(mod_corrente, modulos[i], x, y);
        
        LL diff = resto_corrente - restos[i];
        if (diff % mdc != 0) {
            return -1; // Sistema inconsistente
        }
        
        LL fator = diff / mdc;
        x = (x * fator) % modulos[i];
        if (x < 0) x += modulos[i]; // Ajuste para não-negativo
        
        resto_corrente = resto_corrente - mod_corrente * x;
        mod_corrente = mod_corrente / mdc * modulos[i];
        resto_corrente = ((resto_corrente % mod_corrente) + mod_corrente) % mod_corrente;
    }
    
    return resto_corrente;
}

Esta implementação assume que os vetores restos e modulos contêm os \(r_i\) e \(m_i\) respectivamente. A solução retornada é o menor inteiro positivo \(x\) que satisfaz o sistema, ou -1 se não houver solução.

Tags: C++ Teorema Chinês do Resto Algoritmo de Euclides Estendido Congruências Teoria dos Números

Publicado em 6-12 22:51 por Thomas