※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 11525번 문제인 Farey Sequence Length이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/11525
11525번: Farey Sequence Length
Given a positive integer, N, the sequence of all fractions a / b with (0 < a b), (1 < b N) and a and b relatively prime, listed in increasing order, is called the Farey Sequence of order N. For example, the Farey Sequence of order 6 is: 0/1, 1/6, 1
www.acmicpc.net
주어진 수열에서 (\(\frac{0}{1}\)을 제외하면) 분모가 \(n\)인 분수는 분자로 \(n\) 이하임과 동시에 \(n\)과 서로소인 양의 정수만을 가짐을 관찰하자. 따라서 \(n<N\)인 수열에서 분모가 \(n\)인 분수의 개수는 \(\phi(n)\)과 같음을 알 수 있다. (단, \(n=1\)의 경우는 2이다.)
10000 이하의 양의 정수들에 대하여 euler phi함수의 값을 미리 계산한 다음 prefix sum을 구해 문제를 해결하자.
여담으로, \(n\)차 페리 수열(Farey Sequence of order \(n\))은 0 이상 1 이하의 유리수 중 분모가 \(n\) 이하인 기약분수로 나타낼 수 있는 수를 오름차순으로 나열한 수열이다. 이 수열은 독특한 성질이 많아 유리수 관련 문제를 풀 때 종종 사용하기 좋으므로 스턴-브로콧 트리(Stern-Brocot Tree)와 함께 잘 알아두면 좋은 개념이다.
아래는 제출한 소스코드이다.
// Euler-phi
#include <iostream>
using namespace std;
int A[10001];
void init() {
A[0] = 1;
for (int i = 1; i < 10001; i++) {
int ii = i, val = i;
for (int k = 2; k * k <= ii; k++) {
if (ii % k) continue;
val = val / k * (k - 1);
while (!(ii % k)) ii /= k;
}
if (ii > 1) val = val / ii * (ii - 1);
A[i] = A[i - 1] + val;
}
}
int T, idT, x;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
init();
cin >> T;
while (T--) {
cin >> idT >> x;
cout << idT << ' ' << A[x] << '\n';
}
}
'BOJ' 카테고리의 다른 글
[BOJ 7694 // C++] Triangle (0) | 2024.04.02 |
---|---|
[BOJ 15330 // C++] Parallel Lines (0) | 2024.04.01 |
[BOJ 25823 // C++] 조합의 합의 합 (0) | 2024.03.30 |
[BOJ 26090 // C++] 완전한 수열 (0) | 2024.03.29 |
[BOJ 10407 // C++] 2 타워 (0) | 2024.03.28 |