문제 풀이
[백준] 17435번 합성함수와 쿼리
컴영
2020. 9. 1. 18:25
17435 합성함수와 쿼리
문제
함수 f : {1, 2, ..., m}→{1, 2, ..., m}이 있다. 이때 fn : {1, 2, ..., m}→{1, 2, ..., m}을 다음과 같이 정의하자.
* f1(x) = f(x)
* fn+1(x) = f(fn(x))
예를 들어 f4(1) = f(f(f(f(1))))이다.
n과 x가 주어질 때 fn(x)를 계산하는 쿼리를 수행하는 프로그램을 작성하시오.
입력
첫 줄에 정수 m이 주어진다. (1 ≤ m ≤ 200,000)
다음 줄에 f(1), f(2), ..., f(m)이 차례대로 주어진다.
다음 줄에 쿼리의 개수 Q가 주어진다. (1 ≤ Q ≤ 200,000)
다음 Q개의 줄에 각각 정수 n과 x가 주어진다. (1 ≤ n ≤ 500,000; 1 ≤ x ≤ m)
출력
주어지는 n, x마다 fn(x)를 출력한다.
풀이)
LCA 알고리즘 중 dp를 이용한 방법을 사용하면 된다.
int arr[i][j] // x = i, 2^j = n 일때의 fn(x)값
arr[i][j+1] = arr[arr[i][j]][j]
코드)
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 33 | #include <stdio.h> using namespace std; #define MAX 20 int m, q; int arr[200001][MAX]; //2^19 = 524,288 int main() { scanf("%d", &m); for (int i = 1; i <= m; i++) { scanf("%d", &arr[i][0]); } scanf("%d", &q); for (int k = 0; k < MAX-1; k++) { for (int i = 1; i <= m; i++) { arr[i][k + 1] = arr[arr[i][k]][k]; } } int n, x; while (q--) { scanf("%d %d", &n, &x); for (int i = MAX-1; i >= 0; i--) { if ((1 << i) & n) { x = arr[x][i]; n -= 1<<i; } } printf("%d\n", x); } return 0; } | cs |