-
[PS] 백준 2749번: 피보나치 수 3 / 11444번: 피보나치 수 6문제해결 2023. 10. 26. 20:06
인풋이 100경이다보니깐 O(N)으로만 해도 분명히 타임아웃이 날거라고 생각했다.
100경을 다 훑을순 없고, 100만으로 나눈 나머지만 출력하라니 대충 규칙이 있겠거니 싶었다.
여러가지 숫자로 실험하며 확인해보니
어떤 숫자 M으로 나눈 나머지로 피보나치를 하면
M - 1, 1, 0, 1, 1, 2, 3, ...
이런 구간이 존재하는 듯 했다.
미리 "M - 1, 1"이 나올때까지의 피보나치 수열을 만들어 두고
Fibonacci[N % 주기]를 출력하면 끝.
끝인줄 알았는데 0ms안에 끝나는 다른 사람들 답을 보고 답을 찾아봤다.
$\begin{pmatrix} F_{n+1}&F_n \\ F_n&F_{n-1} \end{pmatrix} = \begin{pmatrix} 1&1\\1&0 \end{pmatrix} ^ n$
이런 기막힌 식이 있더라. 식 자체는 너무 당연한데 이걸 어떻게 생각해내야지 싶다...
아무튼 행렬제곱 풀 때 풀었던 코드 그대로 이용해서 갖고오니 0ms안에 해결. 같은 코드로 11444번: 피보나치 6도 처리했다.
주기 이용하여 푼 228ms 걸린 코드뭉치
#include <bits/stdc++.h> #include <unordered_map> #define FOR(i, n) for(int i = 0; i < int(n); i++) #define FORL(e, s) for(auto &e : s) #define endl "\n" #define vi vector<int> using namespace std; unordered_map<long long, int> um; int modby = 1000000; long long period = -1; int main() { long long N; cin >> N; um[0] = 0, um[1] = 1; for(long long depth = 2;; depth++) { um[depth] = (um[depth - 1] + um[depth - 2]) % modby; if(um[depth] == modby - 1) { period = depth + 2; um[depth + 1] = 1; break; } } cout << um[N % period] << endl; return 0; }
행렬 제곱 이용하여 푼 코드
#include <bits/stdc++.h> #define FOR(i, n) for(int i = 0; i < int(n); i++) #define FORL(e, s) for(auto &e : s) #define endl "\n" #define vll vector<long long> using namespace std; long long modby = 1000000007; vll mult(vll &v1, vll &v2) { vector<long long> res(2 * 2, 0); FOR(i, 2) FOR(j, 2) FOR(k, 2) res[i * 2 + j] += v1[i * 2 + k] * v2[k * 2 + j]; FORL(e, res) e = e % modby; return res; } int main() { long long N; cin >> N; vll V = { 1, 1, 1, 0 }; vector<vll> vvll; vvll.push_back(V); for(long long i = 1; i < N; i *= 2) vvll.push_back(move(mult(vvll.back(), vvll.back()))); V = { 1, 0, 0, 1}; long long limit = N; while (limit > 0) { long long idx = 0; while(true) { if(static_cast<long long>(pow(2, idx + 1)) > limit) { V = move(mult(V, vvll[idx])); limit -= static_cast<long long>(pow(2, idx)); break; } idx += 1; } } cout << V[1] << endl; }
'문제해결' 카테고리의 다른 글
[PS] 백준 16455번: K번째 수 찾는 함수 (1) 2023.11.01 [PS] 백준 30446번: 회문수 (2) 2023.10.28 [PS] 백준 1748번: 수 이어 쓰기1 (0) 2023.10.25 [PS] 백준 23291번: 어항 정리 (0) 2023.10.25 [PS] 백준 2448번: 별 찍기 - 11 (0) 2023.10.25