ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [백준] 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


    '문제 풀이' 카테고리의 다른 글

    [백준] 4013번 ATM  (0) 2020.09.05
    [백준] 13511번 트리와 쿼리 2  (0) 2020.09.02
    [백준] 3548번 가장 가까운 공통 조상  (0) 2020.08.31
    [백준] 14442번 벽 부수고 이동하기2  (0) 2020.08.31
    [백준] 1701번 Cubeditor  (0) 2020.08.30

    댓글

Designed by Tistory.