백준
[2749번] 피보나치 수3
2744m
2020. 4. 4. 18:38
주어지는 N이 1'000'000'000'000'000'000로 매우 크다.
시간 복잡도가 O(logN)인 방법, 행렬을 통한 분할 정복으로 해결해보았다.
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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | #include <iostream> #include <vector> #include <math.h> #include <string.h> #define ll long long #define MOD 1'000'000 #define MAXIUM 1'000'000'000'000'000'000 using namespace std; struct matrix { ll arr[2][2]; matrix() { memset(arr, 0, sizeof(arr)); } matrix(int t) { if (t == 0) { // | 1 0 | arr[0][0] = 1; // | 0 1 | arr[0][1] = 0; arr[1][0] = 0; arr[1][1] = 1; } else if (t == 1) { // | 1 1 | arr[0][0] = 1; // | 1 0 | arr[0][1] = 1; arr[1][0] = 1; arr[1][1] = 0; } } }; //행렬 곱 matrix mult(matrix a, matrix b) { matrix res; res.arr[0][0] = (a.arr[0][0] * b.arr[0][0] + a.arr[0][1] * b.arr[1][0]) % MOD; res.arr[0][1] = (a.arr[0][0] * b.arr[0][1] + a.arr[0][1] * b.arr[1][1]) % MOD; res.arr[1][0] = (a.arr[1][0] * b.arr[0][0] + a.arr[1][1] * b.arr[1][0]) % MOD; res.arr[1][1] = (a.arr[1][0] * b.arr[0][1] + a.arr[1][1] * b.arr[1][1]) % MOD; return res; } //행렬의 제곱 matrix pow(ll n) { if (n == 1) return matrix(1); else { if (n % 2 == 1) { matrix tmp = pow(n / 2); matrix res = mult(tmp, tmp); return mult(res, matrix(1)); } else { matrix tmp = pow(n / 2); matrix res = mult(tmp, tmp); return res; } } } void printmatrix(matrix res,int n) { cout << res.arr[0][0] << ' ' << res.arr[0][1] << '\n'; cout << res.arr[1][0] << ' ' << res.arr[1][1] << '\n'; cout << "fibo(" << n + 1 << ") : " << res.arr[0][0] << '\n'; cout << "fibo(" << n << ") : " << res.arr[1][0] << '\n'; cout << "fibo(" << n - 1 << ") : " << res.arr[1][1] << "\n\n"; } int main() { ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); ll N; cin >> N; ll tmp = N; // 행렬 + 반복분 //matrix res(0);// 단위행렬 //matrix a(1); // 1,1,1,0 //while (tmp > 0) { // if (tmp % 2 == 1) { // res = mult(res, a); // } // a = mult(a, a); // tmp /= 2; //} //cout << res.arr[1][0] % MOD << '\n'; // 행렬 + 재귀호출 matrix res2 = pow(N); cout << res2.arr[1][0]%MOD << '\n'; return 0; } | cs |