朴素欧几里得定理
代码:
int gcd(int a,int b){//a>=b
if(b==0)return a;
return gcd(b,a%b);
}
不定方程
==在已知整数a,b的情况下求a*x+b*y=gcd(a,b)
的一组整数解x,y==
这样的方程一定有解
x1=y2,y1=x2-a/b*y2;
证明略(核心就是把a%b换成a-k*b,然后展开、移项)
代码:
int gcd(int a,int b,int &x1,int &y1){
if(b==0){x1=1,y1=0;return a;}
int x2,y2,d;
d=gcd(b,a%b,x2,y2);
x1=y2,y1=x2-a/b*y2;
return d;
}
==在已知整数a,b的情况下求a*x+b*y=c
的一组整数解x,y==
无解判定
如果c%gcd(a,b)!=0
,则原方程无解,反则有解
通解
设x’,y’为a*x+b*y==gcd(a,b)
的一组解,x,y为a*x+b*y==c(c%gcd(a,b)==0)
的解。令d=gcd(a,b)
,那么有:
x=x'*c/d+k*b/d
,y=y'*c/d+k*a/d
解模线性方程
==a*x≡b(mod n)
==
即a mod n==b mod n
因为(a-b)%n==0
所以,a*x-n*y==b
,用扩欧定理解决
求乘法逆元
逆元记为a^(-1),与普通的倒数不同,它是mod n意义下的“倒数”,即a*a^(-1)==1(mod n)
。
但a的逆元只在ax-ny==1
有解的时候才存在,即a,n必须互质。在gcd(a,n)==1
的前提下,ax≡b(mod n)
有唯一解,即a的逆元a^(-1)。
用途:除法取模
(a/b)%p
==(a*b^(-1))%p
==(a%p)*(b^(-1)%p)%p
代码:
int gcd(int a,int b,int x,int y){
if(b==0){x=1,y=0;return a;}
int xx,yy,d;
d=gcd(b,a%b,xx,yy);
x=yy,y=xx-a/b*yy;
return d;
}
int Inverse(int a,int b){
int x,y;
if(gcd(a,b,x,y)==1)return ((x%b)+b)%b;
return -1;//不存在逆元
}