https://www.acmicpc.net/problem/2725
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
int[] count = new int[1001];
count[1] = 3;
int tmp;
for(int i=2;i<1001;i++){
tmp = 0;
for(int j=1;j<i;j++){
if(gcd(i,j)==1) tmp++;
}
count[i] = count[i-1] + tmp*2;
}
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int C = Integer.parseInt(in.readLine());
StringBuilder sb = new StringBuilder();
for(int i=0;i<C;i++){
sb.append(count[Integer.parseInt(in.readLine())]).append('\n');
}
System.out.print(sb);
}
public static int gcd(int a, int b){
if(b==0) return a;
return gcd(b,a%b);
}
}
count
배열을 이용해 N=1부터 N=1000까지의 각 N에 대한 보이는 점의 개수를 미리 계산합니다. N=1N = 1 N=1000N = 1000 NNcount[1] = 3
은 N=1일 때의 보이는 점을 나타냅니다. N=1N = 1tmp
에 저장하고, 이를 통해 count[i] = count[i-1] + tmp*2
로 업데이트합니다. N=2N = 2 10001000 x=1x = 1 N−1N-1 yy gcd(x,y)=1gcd(x,y) = 1count[N]
에서 조회하여 출력합니다. CC NNgcd
메서드를 통해 두 수의 최대 공약수를 재귀적으로 계산합니다.count
배열에 저장합니다. 이를 통해 각 테스트 케이스에서 빠르게 결과를 조회할 수 있습니다.count[1] = 3
: N=1일 때 보이는 점은 (1,0), (0,1), (1,1)로 총 3개입니다. N=1N = 1 (1,0)(1,0) (0,1)(0,1) (1,1)(1,1)tmp
를 증가시킵니다. ii jjcount[i] = count[i-1] + tmp*2
:tmp
: 현재 N=i일 때, x=i와 y=1부터 i−1까지 중 gcd(i,j)=1인 y의 개수입니다. N=iN = i x=ix = i y=1y = 1 i−1i-1 gcd(i,j)=1gcd(i,j) = 1 yytmp*2
: (i,j)와 (j,i)는 서로 다른 점이므로 두 점을 모두 세기 위해 2를 곱합니다. (i,j)(i,j) (j,i)(j,i)count[i-1]
: 이전 N=i−1까지의 보이는 점 개수를 가져와서 현재 N=i일 때의 보이는 점 개수를 누적합니다. N=i−1N = i-1 N=iN = icount
배열에 저장합니다. N=1N = 1 N=1000N = 1000count[N]
을 조회하여 결과를 얻을 수 있습니다.외부 루프: O(N)
O(N)O(N)
내부 루프: ∑i=2NO(ilogi) → O(N2logN)
∑i=2NO(ilogi)\sum_{i=2}^{N} O(i \log i)
O(N2logN)O(N^2 \log N)
따라서, 사전 계산 부분의 총 시간 복잡도는 O(N2logN)O(N^2 \log N)O(N2logN)입니다. 여기서 N=1000N = 1000N=1000이므로, 총 106×log1000≈106×10=10710^6 \times \log 1000 \approx 10^6 \times 10 = 10^7106×log1000≈106×10=107 정도의 연산이 필요합니다. 이는 제한 시간 내에 충분히 수행 가능합니다.
tmp
에 저장합니다. N=iN = i x=ix = i y=1y = 1 i−1i-1 yy gcd(i,y)=1gcd(i,y) = 1tmp*2
를 count[i]
에 더합니다. (i,y)(i,y) (y,i)(y,i)count[1001]
):gcd
):BufferedReader
, StringBuilder
):System.out.println
을 호출하는 것보다 훨씬 빠릅니다.