数论--gcd

发布于:2023-01-21 ⋅ 阅读:(473) ⋅ 点赞:(0)
  1. 辗转相除法:

原理:

gcd ⁡ ( x , y ) = gcd ⁡ ( y , x   m o d   y ) \gcd(x,y) = \gcd(y,x \bmod y) gcd(x,y)=gcd(y,xmody)

证明:

z z z x , y x,y x,y 的最大公约数。

z ∣ x  ,  z ∣ y z|x \text{ , } z|y zx , zy ,则 z ∣ ( y − x ) z|(y-x) z(yx)

所以:

gcd ⁡ ( x , y ) = gcd ⁡ ( x , x − k × y ) = gcd ⁡ ( y , x   m o d   y ) ( k × y ≤ x < ( k + 1 ) × y ) \gcd ( x , y ) = \gcd ( x , x- k \times y) = \gcd ( y , x \bmod y) (k \times y \le x <(k+1) \times y) gcd(x,y)=gcd(x,xk×y)=gcd(y,xmody)(k×yx<(k+1)×y)

x < y x<y x<y 时:

x   m o d   y = x x \bmod y = x xmody=x

所以:

gcd ⁡ ( x , y ) = gcd ⁡ ( y , x ) \gcd (x , y ) = \gcd (y,x) gcd(x,y)=gcd(y,x)

y < x y<x y<x 时:

gcd ⁡ ( x , y ) = gcd ⁡ ( y , x   m o d   y ) \gcd(x,y) = \gcd(y,x \bmod y) gcd(x,y)=gcd(y,xmody)

y = = 0 y==0 y==0 时,答案为 x x x

int gcd(int x,int y)
{
	return y==0?x:gcd(y,x%y);
}
  1. 二进制算法:

通过不断筛去因子 2 2 2 来提高效率。

x = y x=y x=y ,则 gcd ⁡ ( x , y ) = x \gcd (x,y) =x gcd(x,y)=x ,否则:

  • x , y x,y x,y 为偶数,则 gcd ⁡ ( x , y ) = 2 × gcd ⁡ ( x / 2 , y / 2 ) \gcd (x,y) =2 \times \gcd (x/2,y/2) gcd(x,y)=2×gcd(x/2,y/2)

  • x x x 为偶数, y y y 不为偶数,则 gcd ⁡ ( x , y ) = gcd ⁡ ( x / 2 , y ) \gcd (x,y) = \gcd(x/2,y) gcd(x,y)=gcd(x/2,y)

  • y y y 为偶数, x x x 不为偶数,则 gcd ⁡ ( x , y ) = gcd ⁡ ( x / 2 , y ) \gcd (x,y) = \gcd(x/2,y) gcd(x,y)=gcd(x/2,y)

  • x , y x,y x,y 均不为偶数,则 gcd ⁡ ( x , y ) = gcd ⁡ ( x − y , y ) \gcd(x,y)= \gcd (x-y,y) gcd(x,y)=gcd(xy,y)

int GCD(int x,int y)
{
	if(x==0)return y;
	if(y==0)return x;
	int i=0,j=0;
	for(; (x&1)==0; i++)x>>=1;
	for(; (y&1)==0; j++)y>>=1;
	i=min(i,j);
	while(1)
	{
		if(x<y)swap(x,y);
		if(0==(x-=y))return y<<i;
		while((x&1)==0)x>>=1;
	}
}


网站公告

今日签到

点亮在社区的每一天
去签到