拓展欧几里得和小费马定理求逆元以及推导(学习总结)

相关概念引入:

逆元:假如ax≡1(mod m)则称a关于1模m的逆元为x。当然了x有解的前提是gcd(a,m)=1。

小费马定理:p为质数,ap≡a(mod p),若gcd(a,p)=1,则
a(p-1)≡1(mod p)------- a*a(p-2)≡1(mod p)所以a(p-2)为a的逆元;结合快速幂求a(p-2)

long long quick_pow(int a,int b)
{
	long long sum=1;
	while(b>0)
	{
		if(b&1)
		sum*=a;
		a*=a;
		b>>=1;
	}
}

介绍了小费马定理顺便学习一下欧拉定理
欧拉定理: 若gcd(a,m)=1,则aφ(m)=1(mod m) ;φ(m)为所有比m小且与m互质的数的个数(互质:两个数的gcd等于1)
与小费马定理对比一下。(如果m为质数那么,φ(m)=m-1,任意比m小的数都与m互质)

欧几里得定理:辗转相除法,用于求两个数的最大公约数。
具体做法就是:

int gcd(int a,int b)
{
	if(b==0)
	return a;
	else
	return gcd(b,a%b);
}

不断的用上一次的除数去除以上一次的余数。
拓展欧几里得: 逆元是ax≡1(mod m)即ax=1+km;
解一元二次方程组ax+by=gcd(a,b);观察欧几里得算法可以知道当a=gcd,b=0时终止。如果应用在上面的方程组中则当a=gcd时x=1,b=0时y的值不用管。是否能够由终极形态向上推出最初的x和y的解呢,当然可以.由欧几里得算法我们可以知道gcd(a,b)=gcd(b,a%b).假如我们下一个状态:b * x1+a%b * y1=gcd(a,b)一组解x1,y1。而a%b=a-a/b*b。
所以
b * x1 + (a - a / b * b) * y1=gcd(a,b)

b * (x1 - a/b * y1) + a * y1=gcd(a,b)
对比求解的方程组ax+by=gcd(a,b);
x=y;
y=x-a/b*y;

void exgcd(int a,int b)
{
	if(b==0)
	{
		x=1;
		y=0;
	}
	else
	{
		exgcd(b,a%b);
		int tmp=x;
		x=y;
		y=tmp-a/b*y;
	}
}
void finv(int a,int b)
{
	exgcd(a,b);
	x=(x%b+b)%b;//防止x<0
}

你可能感兴趣的:(数论学习,gcd)