扩展欧几里得算法与唯一分解定理

欧几里得算法

  欧几里得算法又称辗转相除法。

功能

  首先说一下这个算法是用来干啥的。
  欧几里得算法的作用是求两个数 a a a b b b的最大公约数,即 g c d ( a , b ) gcd(a,b) gcd(a,b).

算法过程

  这里再说一下怎么用这个算法求两个数 a a a b b b的最大公约数。
  我们不妨设 a > b a>b a>b
  我们发现如果 b b b a a a的约数,那么 b b b就是二者的最大公约数。我们讨论不能整除的情况,即 a = b ∗ q 1 + r 1 a = b * q_1 + r_1 a=bq1+r1,其中 a , b , q 1 , r 1 a,b,q_1,r_1 a,b,q1,r1都是整数、 r 1 = a % b r_1=a\%b r1=a%b,我们通过证明可以得到 g c d ( a , b ) = g c d ( b , a % b ) gcd(a,b)=gcd(b,a \% b) gcd(a,b)=gcd(b,a%b).

证明

  我们只需要证明 a a a b b b b b b a % b a\%b a%b 有相同的公因子。
  我们设 d d d a a a b b b 的最大公因子,即 d ∣ a d|a da(表示d是a的因子)且 d ∣ b d|b db.注意到 r = a − b ∗ q r=a-b*q r=abq,所以 d ∣ r d|r dr。又因为 d ∣ b d|b db,所以 d d d b b b r r r的公因子。
  反之,如果设 d ∣ b d|b db d ∣ ( a % b ) d|(a\%b) d(a%b),我们知道 a = b ∗ q + r a=b*q+r a=bq+r,所以 d ∣ a d|a da,又因为 d ∣ b d|b db,所以 d d d a a a b b b的公因子。
  既然两式的公因子相同,那么两式的最大公因子也相同。即 g c d ( a , b ) = g c d ( b , a % b ) gcd(a,b)=gcd(b,a \% b) gcd(a,b)=gcd(b,a%b).
  由此,我们可以持续递归操作,等到 b = = 0 b==0 b==0,即上一步 a % b = = 0 a\%b==0 a%b==0的情况下,求得 a a a b b b的最大公约数。
代码:

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

扩展欧几里得算法

  扩展欧几里得算法又称裴蜀定理或贝祖定理,可以用来求一元线性同余方程的解,也即是求一元二次方程的解。

内容

  定理:设 a a a, b b b是不全为零的整数,则存在整数 x x x, y y y,使得 a ∗ x + b ∗ y = g c d ( a , b ) a*x+b*y=gcd(a,b) ax+by=gcd(a,b).
  这个算法是用来判断一元二次方程 a x + b y = c ax+by=c ax+by=c是否存在整数解,如果存在求出其的通解。

求解过程

  这里给出结论,不做证明,当 g c d ( a , b ) ∣ c gcd(a,b)|c gcd(a,b)c时,一元二次方程有整数解,否则,无整数解。
  求解过程:我们假设 a ≥ b a\ge b ab可知 a = b ∗ q + r a=b*q+r a=bq+r r = a − b ∗ q r=a-b*q r=abq,由 g c d ( a , b ) = g c d ( b , a % b ) gcd(a,b)=gcd(b,a \% b) gcd(a,b)=gcd(b,a%b)知, a x 1 + b y 1 = c ax_1+by_1=c ax1+by1=c b x 2 + r y 2 = c bx_2+ry_2=c bx2+ry2=c有相同的解。即 a x 1 + b y 1 = b x 2 + r y 2 ax_1+by_1=bx_2+ry_2 ax1+by1=bx2+ry2,如果我们知道 x 2 x_2 x2 y 2 y_2 y2,我们就可以求 x 1 x_1 x1 y 1 y_1 y1
a x 1 + b y 1 = b x 2 + r y 2 ax_1+by_1=bx_2+ry_2 ax1+by1=bx2+ry2 ∵ r = a − b ∗ q \because r=a-b*q r=abq ∵ q = ⌊ a b ⌋ \because q=\left\lfloor\dfrac{a}{b}\right\rfloor q=ba ∴ a x 1 + b y 1 = b x 2 + ( a − ⌊ a b ⌋ ∗ b ) y 2 \therefore ax_1+by_1=bx_2+(a-\left\lfloor\dfrac{a}{b}\right\rfloor *b)y_2 ax1+by1=bx2+(abab)y2 ∴ a x 1 + b y 1 = b x 2 + a y 2 − ⌊ a b ⌋ ∗ b y 2 \therefore ax_1+by_1=bx_2+ay_2-\left\lfloor\dfrac{a}{b}\right\rfloor *by_2 ax1+by1=bx2+ay2baby2 ∴ a x 1 + b y 1 = a y 2 + b ( x 2 − ⌊ a b ⌋ y 2 ) \therefore ax_1+by_1=ay_2+b(x_2-\left\lfloor\dfrac{a}{b}\right\rfloor y_2) ax1+by1=ay2+b(x2bay2) ∴ x 1 = y 2 \therefore x_1=y_2 x1=y2 ∴ y 1 = x 2 − ⌊ a b ⌋ y 2 \therefore y_1=x_2-\left\lfloor\dfrac{a}{b}\right\rfloor y_2 y1=x2bay2
  我们知道一直递归当 b = = 0 b==0 b==0时开始返回,那么当 b = = 0 b==0 b==0时, x n x_n xn y n y_n yn应该是多少呢?首先我们来看一下当 b = = 0 b==0 b==0时的一元二次方程是什么?答案是: a x n = c ax_n=c axn=c,对于这个结果我们分开讨论。
  当 g c d ( a , b ) = = c gcd(a,b)==c gcd(a,b)==c,所以 x n = 1 x_n=1 xn=1,为了方便计算,我们令 y n = 0 y_n=0 yn=0,到此我们求出 x n x_n xn y n y_n yn,当我们求出递归本层的 x n x_n xn y n y_n yn,我们就可以计算出上一层的 x n − 1 x_{n-1} xn1 y n − 1 y_{n-1} yn1,依次最终可以求出 x 1 x_1 x1 y 1 y_1 y1,这既是一元二次方程的整数解。
  当 g c d ( a , b ) ∣ c gcd(a,b)|c gcd(a,b)c,所以 x n = c g c d ( a , b ) x_n=\dfrac{c}{gcd(a,b)} xn=gcd(a,b)c, x n x_n xn是一个整数,相当于对最终的解扩大了 c g c d ( a , b ) \dfrac{c}{gcd(a,b)} gcd(a,b)c,所以我们可以先求出当 g c d ( a , b ) = = c gcd(a,b)==c gcd(a,b)==c的解,在此基础上扩大 c g c d ( a , b ) \dfrac{c}{gcd(a,b)} gcd(a,b)c倍。
  当 g c d ( a , b ) gcd(a,b) gcd(a,b)不是 c c c的一个因子,那么 x n = c g c d ( a , b ) x_n=\dfrac{c}{gcd(a,b)} xn=gcd(a,b)c, x n x_n xn不是一个整数,那么最终解非整数,即一元二次方程无整数解。
  到此我们给出了一元二次方程解的所有情况,我们知道当存在整数解时,求得的一元二次方程的解不止一个。我们可以求出其通解为 x = x + b / d ∗ k x=x+b/d*k x=x+b/dk, y = y − a / d ∗ k y=y-a/d*k y=ya/dk.
下面给出代码:

int exgcd(int a,int b, int &x,int &y)
{
	if(b==0)
	{
		x=1;
		y=0;
		return a;
	}
	int d = exgcd(b,a%b,x,y);
	int x1 = x;
	x = y;
	y = x1-a/b*y;
	return d;
}
int main()
{
	int a,b,c,x,y;
	scanf("%d%d%d",&a,&b,&c);
	int d = exgcd(a,b,x,y);
	if((a==0&&b==0)||c%d!=0)
	{
		printf("无整数解");
	}
	else
	{	
		int n = c/d;
		x *= n;
		y *= n;
		printf("一个整数解为x=%d y=%d\n",x,y);
		printf("通解为x=x+b/d*k,y=y-a/d*k\n");
	}
	return 0;
}

唯一分解定理

定理

  每个大于1的正整数n都可以被唯一地写成素数的乘积,在乘积中的素因子按照非降序排列。正整数n的分解式 n = p 1 e 1 ∗ p 2 e 2 ∗ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ∗ p k e k n=p_1^{e_1}*p_2^{e_2}*······*p_k^{e_k} n=p1e1p2e2pkek,称为n的标准分解式,其中 p 1 p_1 p1, p 2 p_2 p2, ⋅ ⋅ ⋅ ··· , p k p_k pk是素数, p 1 ≤ p 2 ≤ ⋅ ⋅ ⋅ ≤ p k p_1 \le p_2 \le ···\le p_k p1p2pk,且 e 1 e_1 e1, e 2 e_2 e2, ⋅ ⋅ ⋅ ··· , e k e_k ek是正整数。

性质

  1. 若n的标准素因子分解表达式为 n = p 1 e 1 ∗ p 2 e 2 ∗ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ∗ p k e k n=p_1^{e_1}*p_2^{e_2}*······*p_k^{e_k} n=p1e1p2e2pkek,设d(n)为n的正因子的个数。s(n)为n的所有因子之和,则有 d ( n ) = ( e 1 + 1 ) ∗ ( e 2 + 1 ) ∗ ⋅ ⋅ ⋅ ∗ ( e k + 1 ) d(n)=(e_1+1)*(e_2+1)*···*(e_k+1) d(n)=(e1+1)(e2+1)(ek+1) s ( n ) = p 1 e 1 + 1 − 1 p 1 − 1 ∗ p 2 e 2 + 1 − 1 p 2 − 1 ∗ ⋅ ⋅ ⋅ ∗ p k e k + 1 − 1 p k − 1 s(n)= \dfrac{p_1^{e_1+1}-1}{p_1-1}* \dfrac{p_2^{e_2+1}-1}{p_2-1}*···* \dfrac{p_k^{e_k+1}-1}{p_k-1} s(n)=p11p1e1+11p21p2e2+11pk1pkek+11
    上边公式不做证明,给出解释。例如 n = 12 n=12 n=12 n n n的因子有 1 , 2 , 3 , 4 , 6 , 12 1,2,3,4,6,12 1,2,3,4,6,12,通过暴力计算,因子个数 d 1 ( 12 ) = 6 d_1(12)=6 d1(12)=6,因子和 s 1 ( 12 ) = 28 s_1(12)=28 s1(12)=28,唯一分解式 12 = 2 2 ∗ 3 1 12=2^2*3^1 12=2231,通过公式计算,因子个数 d ( 12 ) = ( 2 + 1 ) ∗ ( 1 + 1 ) = 6 d(12)=(2+1)*(1+1)=6 d(12)=(2+1)(1+1)=6,因子和 s ( 12 ) = 2 2 + 1 − 1 2 − 1 ∗ 3 1 + 1 − 1 3 − 1 = 7 ∗ 4 = 28 s(12)= \dfrac{2^{2+1}-1}{2-1}* \dfrac{3^{1+1}-1}{3-1}=7*4=28 s(12)=2122+113131+11=74=28
  2. a = p 1 α 1 ∗ p 2 α 2 ∗ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ∗ p k α k a=p_1^{α_1}*p_2^{α_2}*······*p_k^{α_k} a=p1α1p2α2pkαk, b = p 1 β 1 ∗ p 2 β 2 ∗ ⋅ ⋅ ⋅ ⋅ ⋅ ⋅ ∗ p k β k b=p_1^{β_1}*p_2^{β_2}*······*p_k^{β_k} b=p1β1p2β2pkβk,则有: g c d ( a , b ) = p 1 m i n ( α 1 , β 1 ) ∗ p 2 m i n ( α 2 , β 2 ) ∗ ⋅ ⋅ ⋅ ∗ p k m i n ( α k , β k ) gcd(a,b)=p_1^{min(α_1,β_1)}*p_2^{min(α_2,β_2)}*···*p_k^{min(α_k,β_k)} gcd(a,b)=p1min(α1,β1)p2min(α2,β2)pkmin(αk,βk) l c m ( a , b ) = p 1 m a x ( α 1 , β 1 ) ∗ p 2 m a x ( α 2 , β 2 ) ∗ ⋅ ⋅ ⋅ ∗ p k m a x ( α k , β k ) lcm(a,b)=p_1^{max(α_1,β_1)}*p_2^{max(α_2,β_2)}*···*p_k^{max(α_k,β_k)} lcm(a,b)=p1max(α1,β1)p2max(α2,β2)pkmax(αk,βk)
  3. 如果 a a a b b b是正整数,则: l c m ( a , b ) = a ∗ b / g c d ( a , b ) lcm(a,b)=a*b/gcd(a,b) lcm(a,b)=ab/gcd(a,b)
  4. n ! n! n!的素因子分解中的素数p的幂为: ⌊ n p ⌋ + ⌊ n p 2 ⌋ + ⌊ n p 3 ⌋ + ⋅ ⋅ ⋅ \left\lfloor\dfrac{n}{p}\right\rfloor+\left\lfloor\dfrac{n}{p^2}\right\rfloor+\left\lfloor\dfrac{n}{p^3}\right\rfloor+··· pn+p2n+p3n+
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值