본문 바로가기
백준

백준 피보나치 수 6

by 콩순이냉장고 2022. 10. 20.

문제 URL : https://www.acmicpc.net/problem/11444

 

11444번: 피보나치 수 6

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

www.acmicpc.net

 

문제 접근법 : 

피보나치 행렬을 이용하는 문제인데

피보나치 행렬이 있다는것을 알았지만 어떻게 유도해내는지 몰라서 공부해봤습니다. 그것만 유도하면 

해당 수의 n승을 구하면되기때문에 

유도 방법을 알려드리겠습니다.

 

일반적으로 

 

피보나치 공식은 

 

이건 너무쉽고 당연하듯이 여러분도 알고있는공식입니다.

이식을 좀 바꿔보죠

자이렇게 근데 fi=fi 이건 당연한겁니다 그치만 뒤에다 0을 추가해줍니다. 0을 더해도 어차피 그대로니 상관없겠죠?

자그럼 인제 이식들을 연립방정식이라 생각하고 행렬로 바꿔보죠

 

이렇게 바뀝니다. 자그럼 식을 간단하게 바꿔보죠 

 

이렇게 바꿔보죠 그럼 생각해보시면 (Fi+1 Fi)는 A(Fi-1 Fi-2) 였을거라 생각할수있습니다.

이렇게 쉽게 추측할수있죠 그렇다면 실제론

이와같은 식이 성립하겠죠 그렇다면 반복한다면

이와같은식이되고 i가 A행렬은 i개 존재하고 F1=1 이었고 F0은 0이었으니 따라서 최종적으로

.

와같은 식이 나옵니다

 

이걸이용해서 코드를 짜시면 됩니다.

 

소스코드 : 

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
34
35
36
37
38
39
40
41
42
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define vll vector<vector<ll>>
ll mod = 1000000007;
ll n;
vll operator*(vll &x,vll &y) {
    vll z(2vector<ll>(2));
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 2; j++) {
            for (int k = 0; k < 2; k++) {
                z[i][j] += x[i][k] * y[k][j];
            }
            z[i][j] %= mod;
        }
    }
    return z;
}
 
void input() {
    cin >> n;
}
void solve() {
    vll x = { {1,1},{1,0} };
    vll res = { {1,0},{0,1} };
 
    while (n) {
        if (n % 2)
            res = x * res;
        x = x * x;
        n /= 2;
    }
    cout << res[1][0<< "\n";
}
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    input();
    solve();
    
}
cs

 

궁금한점 혹은 모르는점 어떤 질문이든 댓글은 언제나 환영입니다.

 

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

백준 5525 IOIOI  (0) 2022.11.01
백준 1007 벡터 매칭  (1) 2022.11.01
백준 15730 수영장 사장님  (1) 2022.08.04
백준 14554 The Other Way  (0) 2022.08.04
백준 13911 집 구하기  (0) 2022.07.31