线性同余方程

【概念】

1.不定方程:未知数的个数多于方程个数,且未知数受到某些限制(如要求是整数)的方程。

2.同余方程

设函数 f(x)=a_nx^n+a_{n-1}x^{n-1}+...+a_1x+a_0,则称:f(x)\equiv0(mod\:m)是关于模 m 的同余方程

3.线性:方程的未知数次数是一次

4.线性同余方程

线性同余方程是最基本的同余方程,形如 ax \equiv b (mod\: m) 的未知数是 x 的同余式,其中,a、b 是整数,且 a\neq 0 (mod\: m)

【与线性同余方程有关的定理】

1.定理1:对于二元一次方程 a*x+b*y=c ,其等价为 a*x\equiv c(mod \:\,b),该方程有整数解的充分条件是 c \: \, mod \: \, GCD(a,b)=0,若方程有整数解,则共有 GCD(a, b) 个解。

2.定理2:若  x_0y_0 为 a*x+b*y=c 的一组解,则该方程的任一解可表示为:\left\{\begin{matrix}x=x_0+b*t/GCD(a,b) \\ y=y_0-a*t/GCD(a,b) \end{matrix}\right.,t\in Z

注意,上面两个通解公式只能选择其中一个,另一个再根据原方程推出。

3.定理3:若 GCD(a, b) =1,则方程 a*x \equiv c (mod \:\,b) 在 [0, b - 1] 上有唯一解。

【线性同余方程的解的求法】

1.使用扩展欧几里德算法求方程的一组解

根据定理1,对于方程 a*x+b*y=c ,用扩展欧几里德算法求出一组 x_0y_0,即令 a*x_0+b*y_0=GCD(a,b),然后两边同除 GCD(a,b) ,再乘以 c ,即得方程 a*x_0*c/GCD(a,b)+b*y_0*c/GCD(a,b)=c ,因此可知方程的一组解 \left\{\begin{matrix}x=x_0*c/GCD(a,b) \\ y=y_0*c/GCD(a,b) \end{matrix}\right.

2.实际应用

实际中,常常被要求去求最小的正整数的解,先通过扩展欧几里德算法求出方程的一组 x_0y_0,再设 t=b/GCD(a,b) ,通过定理2来拓展方程的解,来调整x的范围,将 a*x_0+b*y_0=c 拓展为 a*(x_0+t*k)+b*(y_0-t*k)=c,k \in Z ,从而使得所得到的 x 尽可能的小,通过式子 x=(x\:\, mod\:\, t+t)\:\,mod\:\,t 来约束结果一定是一个正数,最后所得到的 x 即是一个最小的正整数解。 

例题:青蛙的约会(洛谷-P1516)

【模版】

#include<iostream>
using namespace std;
int Extended_GCD(int a,int b,int &x,int &y)
{
    if(b==0)
    {
        x=1;
        y=0;
        return a;
    }
 
    int temp;
    int gcd=Extended_GCD(b,a%b,x,y);
    temp=x;
    x=y;
    y=temp-a/b*y;
    return gcd;
}
int main()
{
    //形如 ax+by=c
    int a,b,c,x,y;
    cin>>a>>b>>c;
 
    int gcd=Extended_GCD(a,b,x,y);
    if(c%gcd!=0)
        cout<<"无整数解"<<endl;
    else
        cout<<"该方程的一组整数解为:x="<<x*c/gcd<<",y="<<y*c/gcd<<endl;
 
	return 0;
}

猜你喜欢

转载自blog.csdn.net/u011815404/article/details/81302830