问题描述:ios
已知a、b互质,求ax+by=1的一组解算法
扩展欧几里得算法:spa
假如b=1,因为gcd(a,b)=1,所以a=x=1blog
假如b≠1,不妨假设a=kb+r,而且咱们已经求出了bx+ry=1的一组解(x0,y0)ci
bx0+(a-kb)y0=1string
ax1+by1=1it
bx0+ay0-kby0=b(x0-ky0)+ay0=ax1+by1io
x1=y0;y1=x0-ky0class
那么(x1,y1)就是ax+by=1的一组解stream
不断迭代便可
#include<iostream> using namespace std; int exgcd(int a,int b,int &x,int &y) { if(b==0) { x=1; y=0; return a; } int gcd=exgcd(b,a%b,x,y); int x2=x,y2=y; x=y2; y=x2-(a/b)*y2; return gcd; } int main() { int x,y,a,b; cout<<"请输入a和b:"<<endl; cin>>a>>b; cout<<"a和b的最大公约数:"<<endl; cout<<exgcd(a,b,x,y)<<endl; cout<<"ax+by=gcd(a,b) 的一组解是:"<<endl; cout<<x<<" "<<y<<endl; return 0; }
裴蜀定理:
对于任意天然数a,b,若gcd(a,b)=d,那么对于全部整数x,y,必定存在x,y使得ax+by=d成立
设gcd(a1,a2,a3,...,an)=d,那么存在整数x1,x2,...,xn使得a1x1+a2x2+...+anxn=d
(别问我为何)
对于整数a,咱们须要找出整数b,使得a*b %p=1
即解方程ab-kp=1
1.在模为素数p的状况下,有费马小定理
a^(p-1)=1(mod p)
那么a^(p-2)=a^-1(mod p)
也就是说a的逆元为a^(p-2)
2.而在模不为素数p的状况下,有欧拉定理
a^phi(m)=1(mod m) (a⊥m)
同理a^-1=a^(phi(m)-1)
所以逆元x即可以套用快速幂求得了x=a^(phi(m)-1)
3.在有些状况下咱们要求出1到p-1全部数关于p的逆元,能够用递推求逆元
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<algorithm> #include<cstring> using namespace std; int A[100001]; int p; int main() { cin>>p; A[1]=1; for(int i=2;i<=10;i++) { A[i]=(p-(p/i))*A[p%i]%p; printf("%d %d %d\n",i,A[i],(i*A[i])%p); } }