欧几里得定理:gcd(a,b) = gcd(b,a mod b)
证明:
a可以表示成a = kb + r,则r = a mod b
1.假设d是a,b的一个公约数,则有 a|d, b|d,而r = a - kb,因此r|d 因此d是(b,a mod b)的公约数,证明充分性
2.假设d 是(b,a mod b)的公约数,则 :b|d , r|d ,但是a = kb +r 因此d也是(a,b)的公约数,证明必要性 因此(a,b)和(b,a mod b)的公约数是一样的,其最大公约数也必然相等。 当b=0时,(a,0)的最大公约数是a
int gcd(int a,int b)//递归
{
if(a
int gcd(int a,int b)//循环
{
if(a>=1;
a*=a;
}
return ans;
}
扩展欧几里得实现原理:
a' = b, b' = a % b 而言,我们求得 x, y使得 a'x + b'y = gcd(a', b') 由于b' = a % b = a - a / b * b (这里的/是程序设计语言中的除法) 那么可以得到: a'x + b'y = gcd(a', b') ===> bx + (a - a / b * b)y = gcd(a', b') = gcd(a, b) ===> ay +b(x - a / b*y) = gcd(a, b) 因此对于a和b而言,他们的相对应的p,q分别是 y和(x-a/b*y).
解 x,y的方法的理解:
1、显然当 b=0,gcd(a,b)=a。此时 x=1,y=0; 也就是1*a+0*b = a
2、设 ax1+by1=gcd(a,b); 在下一个exgcd里bx2+(a mod b)y2=gcd(b,a mod b); 根据欧几里德原理有 gcd(a,b)=gcd(b,a mod b); 则:ax1+by1=bx2+(a mod b)y2;
即:ax1+by1=bx2+(a-(a/b)*b)y2=ay2+bx2-(a/b)*by2; 根据恒等定理得:x1=y2; y1=x2-(a/b)*y2; 这样我们就得到解 x1,y1 的方法:x1,y1 的值基于 x2,y2。
一些性质:
1:对于任意x0的解都有 x=x0+b/d*t t为任意值这个定理求最小正x解很有用 最小x=(x0%(b/d)+b/d)%(b/d)
2:对于任意解y0都有 y=y0-a/d*t
3: ax=b %p 满足条件b|gcd(a,p) 变形及ax+py=b;就可有扩展欧几里得求出
4:求逆元及ax=1 %p
摸版:
ll exgcd(ll a,ll b,ll &x,ll &y)//扩展欧几里得算法摸版
{
if(b==0){x=1;y=0;return a;}
ll d=exgcd(b,a%b,y,x);
y-=a/b*x;
return d;
}
逆元:
ax=1 %p 则x为a模p的逆元 a为x模p的逆元;
线性递推求法:
inv[1] = 1;
for(i=2;i
费马小定理:
%p gcd(a,p)=1 且p为素数;逆元则为
同余性质:
a=b %p
c=d %p
a+c=b+d %p a*c=c*d %p
(a+c)%p=(a%p+c%p)%p (a*c)%p=(a%p*c%p)%p (a/c)%p=(a%p*(c的逆元)%p)%p