扩展欧几里得所能求的东西:不定方程的某一整数解,同余方程,乘法逆元
首先了解一个性质(裴蜀定理):ax+by=c 有整数解当且仅当c为gcd(a,b)的倍数
然后是两个预备知识:gcd(a,b)=gcd(b,a%b) a%b=a-a/b*b(此处/表示整除)
不定方程的解:
不妨设a>b
另ax1+by1=gcd(a,b) bx2+(a%b)y2=gcd(b,a%b)
因为gcd(a,b)=gcd(b,a%b)
所以 ax1+by1=bx2+(a%b)y2
因为a%b=a-a/b*b
所以ax1+by1=ay2+b(x2-(a/b)*y2)
所以x1=y2 ; y1=x2-(a/b)*y2
这样就可以递归处理 显然当b=0时为边界条件
我们令当b=0时 x=1 y=0
然后慢慢回溯
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#define int long long
using namespace std;
int exgcd(int a,int b,int &x,int &y)
{
int d,t;
if(b==0)
{
x=1;y=0;
return a;
}
d=exgcd(b,a%b,x,y);
t=x-a/b*y;
x=y;
y=t;
return d;
}
signed main()
{
int a,b,x,y,d;
scanf("%lld %lld",&a,&b);
d=exgcd(a,b,x,y);
printf("%lld",(x%(b/d)+(b/d))%(b/d));
}
求出不定方程的最小解
emmm其实就是上面的输出。
因为x%(b/d)可能为负数 所以要加上b/d 然后再模b/d
同余方程
axΞp(mod b)
方程可改写为ax=by+p →ax+by=p(注意此处移项后y的系数并没有取相反数,因为y的值对这个式子没有影响)
显然当p为gcd(a,b)的倍数的时候,有整数解
然后就是emmmm不定方程的解法了
乘法逆元
首先科普一下逆元是什么意思(令a在mob p的情况下逆元的符号为inva)
a*invaΞ1(mod p) 对,这个就是乘法逆元的作用
那么如何用扩展欧几里得求乘法逆元呢
令x=inva b=p
然后就完事了
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
void exgcd(int a,int b,int &x,int &y)
{
int t;
if(b==0)
{
x=1;y=0;
return ;
}
exgcd(b,a%b,x,y);
t=x-a/b*y;
x=y;
y=t;
return ;
}
inline int niyuan(int a,int m)
{
int x,y;
exgcd(a,m,x,y);
return (x%m+m)%m;
}
int main()
{
int n,p;
scanf("%d %d",&n,&p);
for(register int i=1;i<=n;i++)
{
printf("%d\n",niyuan(i,p));
}
}
总结:不管是同余方程还是乘法逆元,都是将其转换为不定方程的形式,再进行扩展欧几里得的运算