최대공약수의 약수는 모든 수들의 공약수이고 최소공배수의 배수는 모든 수들의 배수이다
1. 문제
1565번: 수학
배열 D와, 배열 M이 주어졌을 때, D에 있는 모든 수의 배수이며, M에 있는 모든 수의 약수인 수의 개수를 구하는 프로그램을 작성하시오.
www.acmicpc.net
2. 풀이
수들의 최소공배수의 배수는, 모든 수들의 공배수이며,
수들의 최대공약수의 약수는, 모든 수들의 공약수이다.
M에서 최대공약수를 구한 다음에, 최대공약수의 약수들을 구한다.
$O(\sqrt{N})$으로 구할 수 있다.
여기서 set()을 이용해서 중복을 피해준다
다음 D에서 최소공배수를 구해준다.
a,b의 최소공배수는 a*b/gcd(a,b)로 구할 수 있
그리고 M에서 구한 약수들이 최소공배수의 배수인지 판단해준다
from sys import stdin
def gcd(a,b):
while b != 0:
a,b = b,a%b
return a
def lcm(a,b):
return a*b//gcd(a,b)
d,m = map(int,stdin.readline().split())
D = list(map(int,stdin.readline().split()))
M = list(map(int,stdin.readline().split()))
#M에서 최대공약수를 구한다
gcd_m = M[0]
for i in range(1,m):
gcd_m = gcd(gcd_m,M[i])
#최대공약수의 약수는, M의 모든 수들의 공약수이다.
divisor = set()
for i in range(1,int(gcd_m**(1/2))+1):
if gcd_m % i == 0:
divisor.add(i)
divisor.add(gcd_m//i)
#D에서 최소공배수를 구한다
lcm_d = D[0]
for i in range(1,d):
lcm_d = lcm(lcm_d,D[i])
#약수들이 최소공배수의 배수라면,
#D의 모든 수들의 배수이면서 M의 모든 수들의 약수가 된다
count = 0
for div in divisor:
if div % lcm_d == 0:
count += 1
print(count)
'정수론' 카테고리의 다른 글
harmonic lemma 응용하기 - 올림으로 된 조화수열 합을 빠르게 구하는 방법 (0) | 2023.06.17 |
---|---|
1부터 n까지 모든 자연수들 각각의 약수의 누적합을 구하는 방법들(double counting, harmonic lemma, dynamic programming) (0) | 2023.06.15 |
베주의 항등식 - 최대공약수로 만들 수 있는 정수 (0) | 2023.05.27 |
피보나치 수열 심화과정5 -피보나치 수열의 합을 가장 빠르게 구하는 방법- (0) | 2023.05.27 |
피보나치 수열 심화과정4 -피보나치 수의 최대공약수 놀라운 성질- (0) | 2023.05.26 |
TAGS.