对任何整数 a a a、 b {\displaystyle b} b和 c {\displaystyle c} c,关于未知数 x {\displaystyle x} x和 y {\displaystyle y} y的线性丢番图方程: a x + b y = c {\displaystyle ax+by=c} ax+by=c当且仅当 g c d ( a , b ) ∣ c gcd(a,b)|c gcd(a,b)∣c时有整数解。
先证:
对于任意整数 a , b a,b a,b ,存在一对整数 x , y x,y x,y ,满足 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)。
①在欧几里得算法(Euclidean algorithm)的最后一步,即 b=0 时,显然有一对整数 x = 1 , y = 0 x=1,y=0 x=1,y=0,使得 a × 1 + 0 × 0 = g c d ( a , 0 ) a \times 1+0 \times 0=gcd(a,0) a×1+0×0=gcd(a,0);
②若 b > 0 b>0 b>0 ,则 g c d ( a , b ) = g c d ( b , a m o d b ) gcd(a,b)=gcd(b,a\bmod b) gcd(a,b)=gcd(b,amodb)。假设存在一对整数 x , y x,y x,y ,满足 b × x + ( a m o d b ) × y = gcd ( b , a m o d b ) b \times x+(a \bmod b)\times y=\gcd(b,a\bmod b) b×x+(amodb)×y=gcd(b,amodb)。
那么 b x + ( a m o d b ) ⋅ y = b x + ( a − b ⌊ a b ⌋ ) ⋅ y = a y + b ⋅ ( x − ⌊ a b ⌋ y ) bx+(a \bmod b)·y=bx+(a−b⌊\frac{a}{b}⌋)·y=ay+b· (x−⌊\frac{a}{b}⌋y) bx+(amodb)⋅y=bx+(a−b⌊ba⌋)⋅y=ay+b⋅(x−⌊ba⌋y)
令 x ′ = y , y ′ = x − ⌊ a b ⌋ y x′=y,y′=x−⌊\frac{a}{b}⌋y x′=y,y′=x−⌊ba⌋y,得到 a x ′ + b y ′ = gcd ( a , b ) ax′+by′=\gcd(a,b) ax′+by′=gcd(a,b)。
由数学归纳法,命题成立。
证毕。
又证:
对于更为一般的方程 a x + b y = c ax+by=c ax+by=c,当且仅当 gcd ( a , b ) ∣ c \gcd(a,b)∣c gcd(a,b)∣c,该方程有整数解。
由于证明过程复杂,以下给出简单的感性认识。
我们可以先求出 a x + b y = gcd ( a , b ) ax+by=\gcd(a,b) ax+by=gcd(a,b) 的一组特解 x 0 , y 0 x_0,y_0 x0,y0,然后令$ x_0,y_0$ 同时乘上 c gcd ( a , b ) \frac{c}{\gcd(a,b)} gcd(a,b)c,就得到了 a x + b y = c ax+by=c ax+by=c 的一组特解 c gcd ( a , b ) x 0 , c gcd ( a , b ) y 0 \frac{c}{\gcd(a,b)}x_0,\frac{c}{\gcd(a,b)}y_0 gcd(a,b)cx0,gcd(a,b)cy0。
int ex_gcd(int a,int b,int &x,int &y)//x,y的值也需要返回,在此作为引用。
{
if(!b)
{
x=1;
y=0;
return a;
}
else
{
int gcd=ex_gcd(b,a%b,x,y);
//向上递推
int temp=x;
x=y;
y=temp-a/b*y;
return gcd;
}
}
当且仅当 g c d ( a , b ) ∣ c 时 方 程 有 解 gcd(a,b)|c时方程有解 gcd(a,b)∣c时方程有解。
扩展欧几里得算法能求出 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)的一组特解。当递归至 b = 0 b=0 b=0时,此时该方程有一组解 x = 1 , y = 0 x=1,y=0 x=1,y=0,此值按照规则 x ′ = y , y ′ = x − ⌊ a b ⌋ y x′=y,y′=x−⌊\frac{a}{b}⌋y x′=y,y′=x−⌊ba⌋y 向上层返回。
于是得到一组特解 x 0 , y 0 x_0,y_0 x0,y0使得 a x 0 + b y 0 = gcd ( a , b ) ax_0+by_0=\gcd (a,b) ax0+by0=gcd(a,b),等式两边同时乘上 c gcd ( a , b ) \frac{c}{\gcd(a,b)} gcd(a,b)c,就得到了 a x + b y = c ax+by=c ax+by=c 的一组特解 c gcd ( a , b ) x 0 , c gcd ( a , b ) y 0 \frac{c}{\gcd(a,b)}x_0,\frac{c}{\gcd(a,b)}y_0 gcd(a,b)cx0,gcd(a,b)cy0。
下面给出斐蜀等式的通解:
x = c d x 0 + k b d , y = c d y 0 − k a d ( k ∈ Z , d = g c d ( a , b ) ) x=\frac{c}{d}x_0+k\frac{b}{d},y=\frac{c}{d}y_0-k\frac{a}{d}(k\in Z,d=gcd(a,b)) x=dcx0+kdb,y=dcy0−kda(k∈Z,d=gcd(a,b))
x x x的最小正整数解为 ( x 0 c d mod b + b ) mod b (x_0 \frac{c}{d}\ \text{mod}\ b+b)\ \text{mod}\ b (x0dc mod b+b) mod b。
A line on the plane is described by an equation A x + B y + C = 0 Ax+By+C=0 Ax+By+C=0 . You are to find any point on this line, whose coordinates are integer numbers from − 5 ⋅ 1 0 18 -5·10^{18} −5⋅1018 to 5 ⋅ 1 0 18 5·10^{18} 5⋅1018 inclusive, or to find out that such points do not exist.
The first line contains three integers A A A , B B B and C C C ( − 2 ⋅ 1 0 9 ≤ A , B , C ≤ 2 ⋅ 1 0 9 ) ( -2·10^{9}\le A,B,C\le2·10^{9} ) (−2⋅109≤A,B,C≤2⋅109) —corresponding coefficients of the line equation. It is guaranteed that A 2 + B 2 > 0 A^{2}+B^{2}>0 A2+B2>0 .
If the required point exists, output its coordinates, otherwise output − 1 -1 −1.
一条直线:Ax+By+C=0(AB不同时为0),找到任意一个点(在-5e18~5e18之间)让它的横纵坐标均为整数,或者确定没有这样的点。
输入:A,B,C
输出:该点坐标,没有就输出-1
输入
2 5 3
输出
6 -3
解一个斐蜀方程 a x + b y = − c ax+by=-c ax+by=−c,用扩展欧几里得算法的板子。
#include
#define ll long long
using namespace std;
ll ex_gcd(ll a,ll b,ll &x,ll &y)
{
if(!b)
{
x=1;
y=0;
return a;
}
else
{
ll gcd=ex_gcd(b,a%b,x,y);
//向上递推
ll temp=x;
x=y;
y=temp-a/b*y;
return gcd;
}
}
void solve()
{
ll a,b,c,x,y;
cin>>a>>b>>c;
c=-c;
ll d=ex_gcd(a,b,x,y);
//随便取了一组解
x=x*c/d+b/d*3;
y=y*c/d-a/d*3;
if(c%d) cout<<-1;
else cout<<x<<' '<<y;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
solve();
return 0;
}
给定整数 a , b , n ∈ Z a,b,n\in Z a,b,n∈Z,形如 a x ≡ b ( m o d n ) ax≡b\pmod n ax≡b(modn)的方程称为线性同余方程。我们需要求一个整数 x x x 满足 a x ≡ b ( m o d n ) ax≡b\pmod n ax≡b(modn),或者给出无解。
a x ≡ b ( m o d n ) ax≡b\pmod n ax≡b(modn) 等价于 a x − b ax-b ax−b 是 n n n 的倍数,不妨设为 − y -y −y 倍,即 a x − b = − y n ax-b=-yn ax−b=−yn。于是可以将线性同余方程改写为斐蜀等式的形式 a x + n y = b ax+ny=b ax+ny=b 。由斐蜀定理,当且仅当 g c d ( a , n ) ∣ b gcd(a,n)|b gcd(a,n)∣b 时方程有整数解。
题目描述
求关于 x x x 的同余方程 a x ≡ 1 ( m o d b ) a x \equiv 1 \pmod {b} ax≡1(modb) 的最小正整数解。
输入格式
一行,包含两个正整数 a , b a,b a,b,用一个空格隔开。
输出格式
一个正整数 x 0 x_0 x0,即最小正整数解。输入数据保证一定有解。
输入输出样例
输入
3 10
输出
7
说明/提示
【数据范围】
对于 40%的数据, 2 ≤ b ≤ 1 , 000 2 ≤b≤ 1,000 2≤b≤1,000;
对于 60%的数据, 2 ≤ b ≤ 50 , 000 , 000 2 ≤b≤ 50,000,000 2≤b≤50,000,000;
对于 100%的数据, 2 ≤ a , b ≤ 2 , 000 , 000 , 000 2 ≤a, b≤ 2,000,000,000 2≤a,b≤2,000,000,000。
NOIP 2012 提高组 第二天 第一题
题解
该题的线性同余方程若有解,则 a , b a,b a,b 互质。
需要输出最小正整数解,求得的特解 x 0 x_0 x0 却往往不是最小整数解。
已知等式 a ( x 0 + k b ) + b ( y 0 − k a ) = 1 a(x_0+kb)+b(y_0-ka)=1 a(x0+kb)+b(y0−ka)=1,等式两边同时对 b b b取余,得到 a x 0 m o d b = 1 ax_0\bmod b=1 ax0modb=1 。故取最小整数解为 ( x 0 m o d b + b ) m o d b (x_0\bmod b +b)\bmod b (x0modb+b)modb。
代码
#include
#define ll long long
using namespace std;
ll ex_gcd(ll a,ll b,ll &x,ll &y)
{
if(!b)
{
x=1;
y=0;
return a;
}
else
{
ll gcd=ex_gcd(b,a%b,x,y);
ll temp=x;
x=y;
y=temp-a/b*y;
return gcd;
}
}
void solve()
{
ll a,b,c=1;
cin>>a>>b;
ll x,y;
ex_gcd(a,b,x,y);
x=(x%b+b)%b;
cout<<x;
}
int main()
{
solve();
return 0;
}