Solução
Para esse problema vamos primeiro achar uma recursão que represente o problema:
Pois para cada valor de fibonacci, temos que a quantidade de chamadas recursivas é igual a quantidade de mais mais o dele mesmo .
Agora já poderíamos montar uma matriz 3x3 e resolver o problema com exponenciação rápida, porém podemos deixar o problema mais simples por meio de matemática.
Vamos partir da hipótese que :
Podemos verificar para os casos bases que isso é verdade:
Para o caso geral temos que:
Provando assim por indução que .
Para calcular podemos usar o fato que dado uma matriz , considerando sendo o -ésimo número de Fibonacci, temos que .
Com isso podemos calcular usando a representação em binário de , pois sendo as potências de dois que compôem , com isso usando essa técnica podemos aplicar a mesma idéia em matrizes, e é claro computando sempre os elementos módulo .
Código:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <bits/stdc++.h> | |
using namespace std; | |
typedef unsigned long long ull; | |
struct mat | |
{ | |
ull m[2][2]; | |
mat operator* (const mat &rhs) const | |
{ | |
mat ans = {0, 0, 0, 0}; | |
for (int i = 0; i < 2; i++) { | |
for (int j = 0; j < 2; j++) { | |
for (int k = 0; k < 2; k++) { | |
ans.m[i][j] += m[i][k]*rhs.m[k][j]; | |
} | |
} | |
} | |
return ans; | |
} | |
mat operator% (ull x) const | |
{ | |
mat ans = {0, 0, 0, 0}; | |
for (int i = 0; i < 2; i++) { | |
for (int j = 0; j < 2; j++) { | |
ans.m[i][j] = m[i][j]%x; | |
} | |
} | |
return ans; | |
} | |
}; | |
mat power(mat x, ull b, ull mod) | |
{ | |
mat ans = {1, 0, 0, 1}; | |
while (b) { | |
if (b&1ull) ans = (ans*x) % mod; | |
x = (x*x) % mod; | |
b >>= 1; | |
} | |
return ans; | |
} | |
int main() | |
{ | |
ull n, b; | |
cin >> n >> b; | |
mat fib = {1, 1, 1, 0}; | |
fib = power(fib, n, b); | |
ull ans = 2ull*fib.m[0][0] - 1; | |
ans %= b; | |
cout << ans << "\n"; | |
return 0; | |
} |