問題描述: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); } }