[백준] 17425번 - 약수의 합 (Gold 5)
업데이트:
문제 링크
문제 설명
참고 문제 : 백준 17427번 - 약수의 합 2 (Silver 2)
N을 T개 입력받고, 각각의 N에 대해 g(N)을 출력하는 문제이다.
주의점
- overflow에 주의해야한다.
- $g(N) = O(N^2)$, $g(1000000) \approx 2^{40}$ : int의 범위를 넘는다.
- 시간복잡도에 유의해야한다.
- $O(N \sqrt N)$으로는 시간 초과가 뜬다.
정답 코드 및 설명
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int T = Integer.parseInt(br.readLine());
long g[] = g(1000000);
for(int i = 0; i < T; i++) {
int N = Integer.parseInt(br.readLine());
bw.write(""+g[N-1]);
bw.newLine();
}
bw.close();
}
static long[] g(int N) {
long g[] = new long[N];
long f[] = new long[N];
g[0] = 1;
for(int i = 1; i <= N; i++) {
for(int j = i; j <= N; j += i) {
f[j-1] += i;
}
if(i > 1) g[i-1] = g[i-2] + f[i-1];
}
return g;
}
}
-
백준 17427번 - 약수의 합 2 (Silver 2)처럼 풀 경우 시간 복잡도 : $O(N^2)$
-
$g(1), … , g(1000000)$을 전부 계산하므로 보다 효율적인 계산이 가능하다.
- $g(i) = g(i-1) + f(i)$, $f(i) = \displaystyle \sum_{j|i} j$
- 역으로 생각하기 : $f(i)$를 계산할 때 $j$는 모든 $j$의 배수들에 더해진다.
- 배열 $f[1000000]$을 만들고 $j$의 배수마다 $j$를 더해주면 된다!
- 배열 $f[1000000]$ 계산의 시간 복잡도
- $O(N/1) + O(N/2) + \cdots + O(N/N) = O(N\log N)$
- 전체 시간 복잡도 : $O(N) + O(N\log N) = O(N\log N)$
-
g(N)이 int의 범위를 벗어날 수 있으므로, long으로 구현한다.
댓글남기기