유클리드 호제법
a=qb+r ⟹ gcd(a,b)=gcd(b,r)
유클리드 호제법은 두 수의 최대공약수 뿐만 아니라 ax+by=k⋅gcd(a,b) 같은 선형 방정식을 풀어주기도 한다. 이를 확장 유클리드 호제법이라 부른다.
증명
d=gcd(a,b)면 d ∣ a, d ∣ b로 부터 d ∣ a−qb=r 를 얻는다.
따라서 d는 b와 r의 공약수이다.
임의의 c가 b와 r의 공약수이면 c ∣ qb+r=a 이다.
즉, c는 a와 b의 공약수이기도 하다.
gcd(a,b)=d 이므로 c≤d 이기 때문에 d 는 b와 r의 공약수 중 가장 크다.
그러므로 gcd(b,r)=d 이다. □
과정
실제로 유클리드 호제법이 어떻게 진행되는지 보자.
두 정수 a,b의 gcd(a,b) 를 찾기 위해 나눗셈 정리를 이용해 나열한다.
abr1⋮rn−2rn−1=====q1b+r1 (0<r1<b)q2r1+r2 (0<r2<r1)q3r2+r3 (0<r3<r2)qnrn−1+rn (0<rn<rn−1)qn+1rn+0
나머지가 0이면 최대공약수를 찾은 것이다.
gcd(a,0)=a 이기 때문이다.
이 때의 최대공약수는 rn 이다.
이러한 과정은 유한한 연산끝에 종료된다.
rn=rn−2−qnrn−1 과 같이 표현되고 이는 rn−1,rn−2⋯도 마찬가지 일 것이다.
식을 거슬러 올라가면 a,b 값들도 얻을 수 있고, 이것들이 a,b로 표현될 때 까지 반복하면
ax+by=gcd(a,b)
의 해 (x,y) 를 얻는다.
이를 실제 코드로 나타내는 것은 약간의 최적화를 필요로 한다. 실제로 다시 최대공약수를 찾은다음에 거슬러 올라가서 방정식의 해를 찾기보단, 해를 계속해서 업데이트하며 최대공약수를 찾을때의 해 값이 정답이 되게 한다.
확장 유클리드 호제법 알고리즘
6개의 변수를 유지하며 진행한다.
초기값은 다음과 같다.
- r1=a
- r2=b
- x1=1
- x2=0
- y1=0
- y2=1
그리고 r2=0일 때 까지 다음을 반복한다.
q:=⌊r2r1⌋(r1,r2):=(r2,r1−qr2)(x1,x2):=(x2,x1−qx2)(y1,y2):=(y2,y1−qy2)
이것의 결과는 r2=0 일 때,
r1=gcd(a,b) 이고, (x1,y1)는 ax+by=gcd(a,b) 를 만족하는 해이다.
코드로 나타내면 다음과 같다.
array<int, 3> gcdx(int a, int b) {
int x1 = 1, x2 = 0, y1 = 0, y2 = 1;
while (b) {
int q = a / b - ((a ^ b) < 0 && a % b);
tie(a, b) = mp(b, a - q * b);
tie(x1, x2) = mp(x2, x1 - q * x2);
tie(y1, y2) = mp(y2, y1 - q * y2);
}
return {a, x1, x2};
}
q가 음수가 되면 c++
의 연산상 내림 연산이 다르게 동작하기 때문에 따로 처리해준 것을 볼 수 있다.
유클리드 호제법으로부터 파생되는 정리들
Theorem 2.7
k>0 이면 gcd(ka,kb)=k⋅gcd(a,b)
증명
유클리드 호제법으로 gcd(a,b) 를 찾는 과정을 전개하며 양변에 k를 곱해보자.
ka=kq1b+kr1kb=kq2r1+kr2kr1=kq3r2+kr3⋮krn−2=kqnrn−1+krnkrn−1=kqn+1rn+0
이는 gcd(ka,kb)에 유클리드 호제법을 취하는 과정과 동일하고
이 때의 gcd(ka,kb)=krn=k⋅gcd(a,b) 이다. □
k가 음수일 때도 비슷하게 gcd(ka,kb)=∣ k ∣gcd(a,b) 인 따름 정리가 존재한다.
gcd(n,m)=gcd(n,n−m)
유클리드 호제법은 gcd(n,m)=gcd(m,n%m) 이다.
이것 말고도 gcd(n,m)=gcd(n,n−m) 도 성립한다.
증명
n=qm+r 일 때,
d=gcd(n,m),e=gcd(m,r)
d ∣ n, d ∣ m
d ∣ (n−qm)=r
즉, d ∣ r,d ∣ m 이기 때문에 d ∣ e. ∵e=gcd(m,r)
e ∣ m,e ∣ r 이기 때문에 e ∣ (qm+r)=n
d ∣ e 그리고 e ∣ d 이기 때문에 d=e □
최소공배수
Definition 2.4
0이 아닌 두 정수 a,b의 최소공배수 (least common multiple) 는 다음을 만족하는 양의 정수 m 이며 lcm(a,b)로 표현된다.
- a ∣ m,b ∣ m
- a ∣ c, b ∣ c, c>0 이면 m≤c
Theorem 2.8
gcd(a,b)⋅lcm(a,b)=a⋅b
증명
d=gcd(a,b), a=dq1, b=dq2 라 하자.
m=dab이면 m=da=db=dq1q2
즉, m은 a,b의 공배수이다.
양의 정수 c를 a,b의 공배수 중 하나라고 하자.
c=au=bv
d=ax+by를 만족하는 x,y가 존재하므로
Theorem 2.4
mc=abcd=abc(ax+by)=bc⋅x+ac⋅y=vx+uy
우변이 정수여서 m ∣ c 이므로 m≤c 이고 m 은 최소공배수이다.
∴m=lcm(a,b)=gcd(a,b)ab □
Corollary
임의의 정수 a,b에 대해 lcm(a,b)=ab 이면 gcd(a,b)=1 이다. 역도 성립한다.
Comments