백준 11444번 문제 링크
문제 이름 : 피보나치 수 6
주 언어 : Python
태그 : 수학 / 분할 정복을 이용한 거듭제곱
solved.ac 등급 : Platinum V (2023/03/28 확인)
피보나치 수열 의 성질 (해당 노트에서 기본 성질 참고) 2번에서 [Fn+1FnFnFn−1]=[1110]n 이므로, 행렬의 빠른 거듭제곱을 이용해 문제를 풀 수 있습니다.
혹은 피보나치 수열의 성질에 따라 계산할 수도 있습니다. (성질 6번, 7번)
입력된 수 n에 대해서, F_{n} \pmod{10^{9} + 7}의 값을 구해줍니다.
성질 6번, 7번을 이용하면 재귀적으로 시간복잡도 O(\lg n)에 풀 수 있습니다.
def fibo(n, p): # https://ii-eugene-ii.github.io/Post/Post01000/00019.html | |
# (n번째 피보나치 수 mod p, n + 1번째 피보나치 수 mod p)를 return 하는 함수 | |
if n < 3: return [(0, 1), (1, 1), (1, 2)][n] | |
Fk, Fk1 = fibo(n // 2, p) | |
if n % 2 == 0: | |
return (2 * Fk1 - Fk) * Fk % p, (pow(Fk, 2, p) + pow(Fk1, 2, p)) % p | |
else: | |
return (pow(Fk, 2, p) + pow(Fk1, 2, p)) % p, (2 * Fk + Fk1) * Fk1 % p | |
N = int(input()) | |
print(fibo(N, pow(10, 9) + 7)[0]) |
-번째 푼 문제 (2022/--/--)