线性同余方程
数论中,线性同余方程是最基本的同余方程。线性表示方程的未知数是一次的,即形如:ax ≡ b (mod p), a, b, p ∈ Z
。
推导:
a * x = k1 * n + r ①
b = k2 * n + r ②
联立 ①、② 得:a * x + (k2 - k1) * n = b
由扩展欧几里得算法可知,当且仅当 b 是 a、n 的最大公约数的倍数时,方程有解,根据之前讲的知识,另 x0 表示 a * x0 + n * y0 = gcd(a, n) 的解,则 x 的解集为:
x ∈ {x | x = b / gcd(a, n) * x0 + n / gcd(a, n) * k, k ∈ Z}
最小整数解:
令 t = n / gcd(a, n)
又 x = b / gcd(a, n) * x0 + n / gcd(a, n) * k, k ∈ Z
则最小整数解 xm = x % t
但是,x 的值可能为负,因此实际的 xm = (x % t + t) % t。
一道裸题:
代码:(包含模板函数)
#include <cstdio>
typedef long long ll;
ll la, lb, lx, ly, gcd;
ll exgcd(ll a, ll b, ll& x, ll& y)
{
if (b == 0)
{
x = 1;
y = 0;
return a;
}
int r = exgcd(b, a % b, x, y);
int t = x;
x = y;
y = t - a / b * y;
return r;
}
ll mi(ll a, ll b, ll n)
{
ll x, y, d;
d = exgcd(a, n, x, y);
if (b % d) return -1;
ll t = n / d;
x *= b / d;
x = (x % t + t) % t;
return x;
}
int main()
{
scanf("%lld%lld", &la, &lb);
printf("%lld", mi(la, 1, lb));
//gcd = exgcd(la, lb, lx, ly);
//printf("%lld", (lx % lb + lb) % lb);
}
线性同余方程组
线性同余方程组可用于求解中国剩余定理、扩展中国剩余定理。
孙子定理是中国古代求解一次同余式组(见同余)的方法。是数论中一个重要定理。又称中国余数定理。一元线性同余方程组问题最早可见于中国南北朝时期(公元5世纪)的数学著作《孙子算经》卷下第二十六题,叫做“物不知数”问题,原文如下:
有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二。问物几何?即,一个整数除以三余二,除以五余三,除以七余二,求这个整数。
《孙子算经》中首次提到了同余方程组问题,以及以上具体问题的解法,因此在中文数学文献中也会将中国剩余定理称为孙子定理。
来源:百度百科