※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 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';
	}
}
728x90

'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

+ Recent posts