1.自然语言描述
扩展欧几里得往往用于求线性同余方程 ax≡b(mod m) 的解;方程形式可以写成 ax+my=b ,求解x,y(解并不唯一,可正可负,所以原本是-y可以写成y便于求解)
求解线性同余方程要用到裴蜀定理(贝祖定理)
裴蜀定理:对于一对不全为0的整数a,b,存在整数x,y使得 ax+by=gcd(a,b) 成立。
利用扩展欧几里得算法最后得到a,m的最大公约数(a,m),如果b mod (a,m) 不为0(即b无法被gcd(a,m)整除)则线性同余方程无解,否则有解;线性同余方程的解为x*b/gcd(a,m)(等式两边同时乘以b/gcd(a,m))
2.代码描述
题目:Acwing.877 扩展欧几里得算法题目链接
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int MAXN=1e5+10;
int n;
int exgcd(int a,int b,int &x,int &y)
{
if(!b){//a*x+0*y=a ; x=1,y=0 ; gcd(a,0)=a
x=1,y=0;
return a;
}
int d=exgcd(b,a%b,y,x);//x与y交换位置,适应递归计算
y-=a/b*x;
return d;
}
int main(void)
{
scanf("%d",&n);
while(n--){
int a,b;
scanf("%d%d",&a,&b);
int x,y;
exgcd(a,b,x,y);
printf("%d %d\n",x,y);
}
return 0;
}
题目:Acwing.878 线性同余方程题目链接
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int MAXN=1e5+10;
int n;
LL exgcd(LL a,LL m,int &x,int &y)
{
if(!m){
x=1,y=0;
return a;
}
LL d=exgcd(m,a%m,y,x);
y-=a/m*x;
return d;
}
int main(void)
{
scanf("%d",&n);
while(n--){
int a,b,m;
scanf("%d%d%d",&a,&b,&m);
int x,y;
LL d=exgcd(a,m,x,y);
if(b%d)
printf("impossible\n");
else
printf("%d\n",(b/d)*x%m);//为了保证最后的结果在int范围,同时为了保证答案正确(保持a*x≡b(mod m)),在这里最后的结果要mod m处理
}
return 0;
}