Ir a: Mi propio blog
tema
Ecuación de congruencia Luogu P1082
responder
Defina mcd (a, b) como el máximo común divisor de a, b.
Según el teorema de Euclides:
En particular: mcd (a, 0) = a
Del teorema de Pei Shu:
Algoritmo euclidiano extendido: suponga que a * x + b * y = mcd (a, b)
1. Cuando b = 0, mcd (a, b) = a, la solución es x = 1, y = 0
2.b! = 0, suponga
Se puede transformar de forma equivalente en:
En comparación con la ecuación a * x + b * y = mcd (a, b), obtenemos: x = y ', y = x' - (a / b) * y ', repita la operación, cambie recursivamente x, y para encontrar Obtenga un conjunto de soluciones especiales x0, y0.
Extensión (no hay prueba en este artículo): Sea d = mcd (a, b), para la ecuación más general a * x + b * y = c, hay una solución si y solo si d | c. Suponiendo que un conjunto de soluciones especiales obtenidas de a * x + b * y = d son x0, y0, multiplique ambos lados de la ecuación (c / d), y luego un conjunto de soluciones especiales (c / d) x0 de la ecuación original , (c / d) y0, la solución general de la ecuación original es:
Solución a esta pregunta: La ecuación de congruencia dada en la pregunta es equivalente a a * x + b * y = 1 (y es un número entero), esta pregunta tiene una solución garantizada, entonces mcd (a, b) | 1, es decir, mcd (a, b) = 1. Utilice el algoritmo euclidiano extendido para encontrar la solución especial x0, y0, la solución general de x es x = x0 + k * b (k es un número entero). Tenga en cuenta que en la pregunta se requiere la solución entera positiva más pequeña.
Código
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a,b,x,y;
void exgcd(ll a,ll b,ll &x,ll &y)
{
if(!b) {x=1,y=0; return;}
exgcd(b,a%b,x,y);
ll z=x; x=y; y=z-(a/b)*y;
}
int main()
{
scanf("%lld%lld",&a,&b);
exgcd(a,b,x,y); //求出特解
x=(x%b+b)%b; //求出最小正整数解
printf("%lld\n",x);
return 0;
}