[数论][exgcd]同余方程

Posted lz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[数论][exgcd]同余方程相关的知识,希望对你有一定的参考价值。

题目描述

求关于 x 的同余方程 ax ≡ 1 (mod b)的最小正整数解。

输入

输入只有一行,包含两个正整数 a, b,用一个空格隔开。

输出

输出只有一行,包含一个正整数 x0,即最小正整数解。输入数据保证一定有解。

样例输入

3 10

样例输出

7

提示

对于 100%的数据,2 ≤a, b≤ 2,000,000,000。

思路:exgcd的应用——求解不定方程、求解线性同余方程

-----------------------------------------------------------------------------

下面给出关于ecgcd的详解与模板:(以下讨论的数全为整数)

问题1:给出方程 ax+by=gcd(a,b) ,求解满足方程的x,y的一组解(求解不定方程)

解:  构造一个相同形式的方程——bx1+(a%b)y1=gcd(b,a%b)

         联立上述两个方程:因为由欧几里得定理有gcd(a,b)=gcd(b,a%b),所以ax+by=bx1+(a%b)y1

        因为a%b=a-a/b*b,带入上式并整理得ax+by=ay1+b(x1-a/b*y1)

        对比等式左右两边得x=y1 , y=x1-a/b*y1 

        因此,若知道满足方程bx1+(a%b)y1=gcd(b,a%b)的x1,y1的一组解,就可以得出x,y的一组解

        同理关于方程bx1+(a%b)y1=gcd(b,a%b)的求解也可以用同样的方法由相应的x2,y2得出

        如此递归下去,当递归到最底层b=0时,显然方程的一组解为x=1,y=0

        得到这组解后,便可以回溯得到最顶层方程即ax+by=gcd(a,b)的一组解了。

引理:存在 x , y 使得 ax+by=gcd(a,b)

上述解法,我们可以用递归的方法来实现。

void exgcd(ll a,ll b){//x,y为两参数,a,b为两参数的系数
  if(b==0) y=(x=1)-1;//x,y为全局变量
  else{
    exgcd(b,a%b);
    ll tmp=x;
    x=y;
    y=tmp-a/b*y;
  }
}

上述代码实现了求方程ax+by=gcd(a,b)的一组解x和y,可以由这一组解得到方程的其他多组解:(设x0,y0为一组已知解,x,y为通解)

x=x0+b/gcd(a,b)*k

y=y0+a/gcd(a,b)*k  (其中k为整数)

将通解带入原方程即可验证。

问题2:给出方程 ax+by=r,求解满足方程的x,y的一组解(求解不定方程)

解: 当r%gcd(a,b)!=0时,方程无整数解

        当r%gcd(a,b)==0时,先利用exgcd求出方程ax+by=gcd(a,b)的一组解x0,y0,则有ax+by=r的一组解为x1=x0*r/c,y1=y0*r/c

        原方程的通解为  x=x1+b/gcd(a,b)*k

                                   y=y1+a/gcd(a,b)*k

问题3:求关于 模方程 ax%b=c(ax=c(mod b))的解x(求解线性同余方程)

解:方程转换为 ax+by=c ,即利用exgcd求不定方程的解x,y(最后只需要x的值)

 原方程的通解为x=x0+b/gcd(a,b)*k(其中x0为ax%b=c的其中一解)

设s=b/gcd(a,b),则 x 的最小正整数解为 (x1%s+s)%s

-----------------------------------------------------------------------------

AC代码:

#include <iostream>
#include<cstdio>
#define ll long long
using namespace std;

ll x,y;

void exgcd(ll a,ll b){
  if(b==0) y=(x=1)-1;
  else{
    exgcd(b,a%b);
    ll tmp=x;
    x=y;
    y=tmp-a/b*y;
  }
}

int main()
{
    ll a,b;
    scanf("%lld%lld",&a,&b);
    exgcd(a,b);
    while(x<=0) x+=b;
    printf("%lld\n",x);
    return 0;
}

 

以上是关于[数论][exgcd]同余方程的主要内容,如果未能解决你的问题,请参考以下文章

bzoj-2219 数论之神

数论...

POJ 1061 青蛙的约会 | 同余方程和exGcd

POJ 1061 - 青蛙的约会 - [exgcd求解一元线性同余方程]

扩展欧几里得(exgcd)与同余详解

NEFU 84 - 五指山 - [exgcd求解一元线性同余方程]