版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/HuangXinyue1017/article/details/83240174
Time Limits: 1000 ms Memory Limits: 524288 KB
Description
Input
Output
Sample Input
5 10
Sample Output
8
Data Constraint
Solution
数列的递推公式为:
F[0]=1,F[1]=1,F[n]=F[n−1]+F[n−2](n>=3)
用矩阵可以这么表示:
{FnFn−1}
={Fn−1+Fn−2Fn−1}
={1∗Fn−1+1∗Fn−21∗Fn−1+0∗Fn−2}
={1110}∗{Fn−1Fn−2}
={1110}n−1∗{F1F0}
={1110}n−1∗{10}
于是我们采用矩阵乘法
O(23logN) 顺利解决此题
Code
#include<algorithm>
#include<cstring>
#include<cstdio>
#define fo(i,a,b) for(int i=a;i<=b;++i)
#define fd(i,a,b) for(int i=a;i>=b;--i)
#define ll long long
using namespace std;
const int N=2;
ll n,P;
struct matrix
{
ll a[N][N];
}A,Ans;
matrix mul(matrix A,matrix B)
{
matrix C;
memset(C.a,0,sizeof(C.a));
fo(k,0,1)
fo(i,0,1) if(A.a[i][k])
fo(j,0,1) if(B.a[k][j])
C.a[i][j]=(C.a[i][j]+A.a[i][k]*B.a[k][j]%P)%P;
return C;
}
matrix ksm(matrix A,ll k)
{
matrix S;
fo(i,0,1) fo(j,0,1) S.a[i][j]=(i==j);
for(;k;A=mul(A,A),k>>=1)
if(k&1) S=mul(S,A);
return S;
}
int main()
{
scanf("%lld%lld",&n,&P);
A.a[0][0]=A.a[0][1]=A.a[1][0]=1,A.a[1][1]=0;
Ans=ksm(A,n-1);
printf("%lld",(Ans.a[0][0]+Ans.a[0][1])%P);
}