#矩阵乘法,斐波那契#洛谷 2544 [AHOI2004] 数字迷阵
分析
oeis找规律得到第一列和第二列的通项公式,然后矩阵乘法
代码
#include <cstdio>
#include <cctype>
#include <cstring>
#include <cmath>
#define rr register
using namespace std;
const double T=0.5*(sqrt(5.0)+1);
struct maix{int p[2][2];}A,ANS;
int mod,n,m;
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline signed mo(int x,int y){return x+y>=mod?x+y-mod:x+y;}
inline maix mul(maix A,maix B){
rr maix C; memset(C.p,0,sizeof(C.p));
for (rr int i=0;i<2;++i)
for (rr int j=0;j<2;++j)
for (rr int k=0;k<2;++k)
C.p[i][j]=mo(C.p[i][j],1ll*A.p[i][k]*B.p[k][j]%mod);
return C;
}
signed main(){
n=iut(); m=iut()-1; mod=iut();
ANS.p[0][0]=(long long)(n*T+n-1)%mod;
ANS.p[0][1]=((2*ANS.p[0][0]-n+1)%mod+mod)%mod;
A.p[0][1]=A.p[1][0]=A.p[1][1]=1;
if (m<2) return !printf("%d",ANS.p[0][m]);
for (;m;m>>=1,A=mul(A,A))
if (m&1) ANS=mul(ANS,A);
return !printf("%d",ANS.p[0][0]);
}