BOJ 11444 피보나치 수 6

2020. 9. 18. 23:11·알고리즘/BOJ

www.acmicpc.net/problem/11444

 

11444번: 피보나치 수 6

첫째 줄에 n이 주어진다. n은 1,000,000,000,000,000,000보다 작거나 같은 자연수이다.

www.acmicpc.net

이번에는 나누는 값이 1000000007이다. 

 

www.acmicpc.net/problem/2749

 

2749번: 피보나치 수 3

첫째 줄에 n이 주어진다. n은 1,000,000,000,000,000,000보다 작거나 같은 자연수이다.

www.acmicpc.net

이 문제에서는 나누는 값이 백만이라 피사노 주기를 통해서 구할 수 있었지만 이번 문제에서는

  • 첫째 줄에 n번째 피보나치 수를 1,000,000,007으로 나눈 나머지를 출력한다.

조건 때문에 피사노 주기를 구하려면 시간 초과가 날 것이다.

따라서 행렬 거듭제곱에 대한 지식이 필요한데 행렬의 지식이 부족해서 유튜브를 뒤적거리다

좋은 영상을 발견했다.

www.youtube.com/watch?v=uX2IsIykLJc

이분 영상에서 피보나치 점화식을 행렬로 표현하는데, 조금 더 변형시켜서 

Fn+1 Fn        1  1

Fn Fn-1   은   1  0  의 제곱으로 나타낼 수 있다.

#include <iostream>
#include <vector>
using namespace std;
#define ll long long
#define vii vector<vector<ll>>
#define vi vector<ll>
#define MOD (int)1e6

vii operator* (const vii& a, const vii& b) {
	int sz = a.size();
	vii ret(sz, vi(sz));
	for (int i = 0; i < sz; i++) {
		for (int j = 0; j < sz; j++) {
			for (int k = 0; k < sz; k++) {
				ret[i][j] += a[i][k] * b[k][j];
			}
			ret[i][j] %= MOD;
		}
	}
	return ret;
}

vii power(vii& a, ll b) {
	int sz = a.size();
	vii ret(sz, vi(sz));
	for (int i = 0; i < sz; i++) ret[i][i] = 1;

	while (b) {
		if (b % 2) ret = ret * a;
		b /= 2;
		a = a * a;
	}
	return ret;
}

int main() {
	ll n;
	cin >> n;
	vii A = { {1,1},{1,0} };

	vii ans = power(A, n);

	cout << ans[0][1] << endl;

	return 0;
}

행렬 제곱 문제를 풀었다면 쉽게 풀 수 있는 문제였다.

'알고리즘 > BOJ' 카테고리의 다른 글

백준 2086 피보나치 수의 합  (0) 2020.09.20
BOJ 11778 피보나치 수와 최대공약수  (0) 2020.09.19
BOJ 2749 피보나치 수 3  (0) 2020.09.18
백준 9471 피사노 주기  (0) 2020.09.18
BOJ 1780 종이의 개수  (0) 2020.09.18
'알고리즘/BOJ' 카테고리의 다른 글
  • 백준 2086 피보나치 수의 합
  • BOJ 11778 피보나치 수와 최대공약수
  • BOJ 2749 피보나치 수 3
  • 백준 9471 피사노 주기
khyu2
khyu2
  • khyu2
    dev log
    khyu2
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 알고리즘
        • BOJ
        • Programmers
        • Algorithm
        • SWEA
      • 개발
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    GREEDY
    알고리즘
    다익스트라
    이분탐색
    이분 탐색
    구현
    팰린드롬
    행렬 제곱
    피보나치 수
    분할 정복
    BFS
    SWEA
    완전 탐색
    시뮬레이션
    큐
    피사노 주기
    프로그래머스
    크루스칼
    우선순위 큐
    코딩테스트 연습
    냅색
    MST
    트리
    조합
    소수
    dfs
    dp
    완전탐색
    유니온 파인드
    BOJ
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
khyu2
BOJ 11444 피보나치 수 6
상단으로

티스토리툴바