
문제 링크 : https://www.acmicpc.net/problem/2749
2749번: 피보나치 수 3
첫째 줄에 n이 주어진다. n은 1,000,000,000,000,000,000보다 작거나 같은 자연수이다.
www.acmicpc.net
문제 조건을 딱 보면 알수 있듯이 일반 recursion이나 dp로는 제시간에 불가능하다.
책에서 봐서 머릿속에 얼핏 남아있는 아이디어가 문득 생각났다.
dp같은 경우 점화식의 형태로 나타내는 경우가 많은데, 이 점화식을 풀고 풀어 단순한 식으로 만들 수 있다.
과정은 조금 더 복잡할 수 있지만 프로그램의 실행 속도는 확연히 줄어든다.
Fn을 n번째 피보나치 수라 한다면,

이라는 행렬의 곱으로 나타낼 수 있다.
결국 남은 것은 저 2x2 행렬을 k번 거듭제곱 해주는 것인데, k가 짝수면 k/2 를 한번 계산해서 제곱해주고 k가 홀수면
k-1 과 1으로 나누어 계산해주면 된다.
시간 내에 통과 가능하다!
구현이 막히는 것을 보아하니 많은 노력이 필요할 것 같다.
#include <bits/stdc++.h> using namespace std; vector<long long> base{2, 1, 1, 1}; long long mod = 1e6; string half(string s) { string ret; int num = 0; for (auto c : s) { num *= 10; num += (c - '0'); ret += to_string(num / 2); num %= 2; } if (ret.front() == '0') { ret.erase(0, 1); } return ret; } string s_down(string s) { string ret = s; for (int i = ret.length() - 1; i >= 0; i--) { int cur = ret[i] - '0' - 1; cur = (cur < 0) ? cur + 10 : cur; ret[i] = cur + '0'; if (cur != 9) { break; } } if (ret.front() == '0') { ret.erase(0, 1); } return ret; } vector<long long> mat_mul(vector<long long> &a, vector<long long> &b) { vector<long long> ret(4); int idx = 0; for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { ret[idx++] = ((a[i * 2] * b[j]) % mod + (a[i * 2 + 1] * b[j + 2]) % mod) % mod; } } return ret; } vector<long long> sol(string n) { if (n == "1") { return base; } if ((n.back() - '0') % 2) { n = s_down(n); vector<long long> tmp = sol(n); return mat_mul(tmp, base); } else { vector<long long> tmp = sol(half(n)); return mat_mul(tmp, tmp); } } int main() { string s; cin >> s; long long ret; if (s == "0") { ret = 0; } else if (s == "1" || s == "2") { ret = 1; } else { string n = (s.back() % 2) ? half(s) : s_down(half(s)); vector<long long> vec = sol(n); if (s.back() % 2) { ret = (vec[2] + vec[3]) % mod; } else { ret = (vec[0] + vec[1]) % mod; } } printf("%lld", ret); return 0; }

'Problem Solving > Baekjoon Online Judge' 카테고리의 다른 글
제1회 블롭컵 (0) | 2022.03.01 |
---|---|
#2933 미네랄 (0) | 2022.01.08 |
#15683 감시 (0) | 2022.01.06 |
#14809 경사로 (0) | 2022.01.05 |
#14503 로봇 청소기 (0) | 2022.01.04 |
댓글