땡구리
땡굴 탱굴
땡구리
전체 방문자
오늘
어제
  • 분류 전체보기 (42)
    • AWS (5)
    • 자격증 후기 (8)
    • 백준 풀이 (17)
    • Vue2 (1)
    • Python (0)
    • Elasticsearch (0)
    • FastAPI (0)
    • MySQL (0)
    • 짜잘정보 (3)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 개선 가능

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
땡구리

땡굴 탱굴

백준 / python / 17435. 합성함수와 쿼리
백준 풀이

백준 / python / 17435. 합성함수와 쿼리

2023. 2. 10. 23:18

https://www.acmicpc.net/problem/17435

 

문제 요약

  1. m 개의 숫자가 주어진다.
  2. m 개의 숫자가 각각 $f(1), f(2), \cdots , f(m)$ 일 때, $f_n(x)$ 를 구하라

 

 

풀이 요약

  1. 한 번씩 뛰어 A -> B -> C 라면 두 번씩 뛰어 A->C 이다.
  2. 이걸 $2^i$ 만큼 이동한 경우를 미리 저장해둔다.
  3. n 에 $2^i$ 이 포함되어있다면  현재 위치에서 $2^i$ 번 뛴 곳으로 이동하는 것을 $n_{(2)}$ 의 자릿수만큼 반복한다.

 

주의사항

이 알고리즘은 Sparse Table 을 사용하는 문제이다.

풀이 시간이 나보다 많이 빠른 풀이도 많으니 그 풀이들을 참조하면 좋겠다.

조건문이 많다고 빨라지진 않는다. 오히려 조건문을 위해 반복문이 포함된다면 성능이 나빠진다.

예를 들면 get 함수의 while 문이 없는 것이 낫다.

while 문 대신 이때까지 갱신한 dp 의 줄 수와 i 값을 비교하여 그 차이만큼 dp 줄 수를 추가하면 빠를 것이다.

한 번 해보겠다.

while 문 자체가 없어지진 않았지만, 이미 알고 있는 index 값들에 대한 반복이 없어져서 훨씬 빨라졌다.

# 수정전 코드

from sys import stdin

input = stdin.readline
ans = []

M = int(input())
dp = [[0] * (M + 1) for _ in range(19)]
dp[0] = [0] + list(map(int, input().split()))


# dp[i][x] 를 반환하는 함수
def get(i, x):
    if dp[i][x]:
        return dp[i][x]

    index = 0
    while i > index:
        if not dp[index + 1][x]:
            dp[index + 1][x] = get(index, get(index, x))
        index += 1

    return dp[index][x]


# f_n(x) 를 반환하는 함수
def solve(n, x):
    i = 0
    ans = x
    while n >= (1 << i):
        if n & (1 << i):
            ans = get(i, ans)
        i += 1
    return ans


Q = int(input())

for q in range(Q):
    n, x = map(int, input().split())
    print(solve(n, x))
# 수정 후 코드

from sys import stdin

input = stdin.readline
ans = []

M = int(input())
dp = [[0, *map(int, input().split())]]


# dp[i][x] 를 반환하는 함수
def get(i, x):
    if len(dp) > i:
        return dp[i][x]

    while i >= len(dp):
        dp.append([dp[-1][x] for x in dp[-1]])

    return dp[i][x]


# f_n(x) 를 반환하는 함수
def solve(n, x):
    i = 0
    ans = x
    while n >= (1 << i):
        if n & (1 << i):
            ans = get(i, ans)
        i += 1
    return ans


Q = int(input())

for q in range(Q):
    n, x = map(int, input().split())
    print(solve(n, x))
저작자표시 (새창열림)

'백준 풀이' 카테고리의 다른 글

백준 / python / 14502. 연구소  (0) 2023.02.18
백준 / python / 2206. 벽 부수고 이동하기  (0) 2023.02.13
백준 / python / 2098. 외판원 순회  (0) 2023.02.08
백준 / python / 1939. 중량제한  (1) 2023.02.05
백준 / python / 2251. 물통  (0) 2023.02.04
    '백준 풀이' 카테고리의 다른 글
    • 백준 / python / 14502. 연구소
    • 백준 / python / 2206. 벽 부수고 이동하기
    • 백준 / python / 2098. 외판원 순회
    • 백준 / python / 1939. 중량제한
    땡구리
    땡구리
    잊는게 무서운 겁쟁이

    티스토리툴바