a|b는 b가 a로 나누어 떨어진다는 뜻이다.
더불어 a|b는 a가 b의 약수라는 것을 의미한다.
유클리드 호제법은 GCD GreatestCommonDivisor 알고리즘이라고도 불리우며
어떤 두 수 a와 b의 최대공약수를 구하는 알고리즘이다.
유클리드 호제법은 재귀적으로 실행되며 과정은 다음과 같다.
int gcd(int a, int b){
int c;
while(b){
c=a%b;
a=b;
b=c;
}
return a;
}
확장 유클리드 알고리즘을 배우기 전에는 베주 항등식을 알아두어야 한다.
베주 항등식이란 식 ax+by=g (a,b는 정수) (x,y) 정수 근에 대해 정수 해 (x,y)를 가지려면
g=gcd(a,b)이어야 한다는 성질을 가지고 있다.
확장 유클리드 알고리즘은 a,b가 정수일 때 ax+by=gcd(a,b)(gcd(a,b)=g)형태의 식의 해 (x,y)와 gcd(a,b)를 구하는 알고리즘이다.
이 식의 형태는 베주 항등식과 같다.
따라서 정수 해 (x,y)를 항상 가진다.
a=bq+r로 표현해보자.
그렇다면 식의 형태는 다음과 같을 것이다.
(bq+r)x+by=g
식을 정리하면 새로운 베주 항등식 꼴이 나온다.
b(qx+y)+rx=g
x=y′
y+qx=x′
y=x′−qy′
우리는 정수 해 (x,y)를
이러한 재귀적인 방법을 통해 구할수 있고,
(y′,x′−qy′)이 정수 해가 된다.
확장 유클리드 알고리즘의 종료 여부는 유클리드 알고리즘과 같이 b=0일 때이다.
b=0 이되면 ax+0∗y=g에서 최대공약수 g는 자연스레 x=1일때가 답이 되어 이때
g=a,x=1,y=0 이 된다.
이를 재귀적으로 구현한 코드는 다음과 같다. seastar105님의구현코드
pair<int,pair<int,int>> xGCD(int a, int b) {
if(b == 0) return {a,{1,0}};
pair<int,pair<int,int>> ret = xGCD(b, a%b);
int g, x, y;
g = ret.first;
tie(x,y)=ret.second;
return {g,{y,x-(a/b)*y}};
}
확장 유클리드 알고리즘의 일반해는 다음과 같다.
g,x0,y0=xGCD(a,b)
x=x0+kb/g
y=y0−ka/g
참고 :
오일러 피함수 \(Euler's phi function\) 0 | 2024.11.08 |
---|---|
에라토스테네스의 체로 소인수분해 하기 0 | 2024.09.29 |
페르마의 소정리 0 | 2024.09.01 |
모듈러 역원 Modular Inverse 0 | 2024.09.01 |
댓글 영역