题意:
不难得出以下递推式:
分析:
由于 n 很大,递推上去肯定超时,考虑矩阵加速,但递推式分情况讨论,不容易构造矩阵,先分类讨论:
(1)n 为奇数:
Fn = 2 * Fn-1 + 1,n为奇数,n - 1必为偶数,Fn-1 = 2 * Fn-2
(2)n 为偶数:
Fn = 2 * Fn-1,n为偶数,n - 1必为奇数,Fn-1 = 2 * Fn-2 + 1
得到一般情况下的递推式:
Fn = Fn-1 + 2 * Fn-2 + 1
容易构造以下矩阵:
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
LL c[3][3],b[3][1],n,m;
LL a[3][3] = {{1,2,1},{1,0,0},{0,0,1}};
void init()
{
b[0][0] = 1;
b[1][0] = 0;
b[2][0] = 1;
memcpy(c,a,sizeof(a));
}
void cal_matrix1()
{
LL t[3][1] = {0};
for(int i = 0;i < 3; ++i)
{
for(int j = 0; j < 3; ++j)
t[i][0] = (t[i][0] + c[i][j]*b[j][0]) % m;
}
memcpy(b,t,sizeof(t));
}
void cal_matrix2()
{
LL t[3][3] = {0};
for(int i = 0; i < 3; ++i)
{
for(int j = 0; j < 3; ++j)
{
for(int k = 0; k < 3; ++k)
t[i][j] = (t[i][j] + c[i][k]*c[k][j]) % m;
}
}
memcpy(c,t,sizeof(t));
}
int solve()
{
if(n == 0) return 0 % m;
if(n == 1) return 1 % m; //注意 1 1 这组数据
n -= 1;
while(n)
{
if(n & 1) cal_matrix1();
cal_matrix2();
n >>= 1;
}
return b[0][0] % m;
}
int main()
{
while(cin>>n>>m)
{
init();
cout<<solve()<<endl;
}
return 0;
}