题意:F[ 1 ] = 1 , F[ 2 ] = 1 , F[ 3 ] = F[ 2 ] + F[ 1 ] ,....F[ n ] = F[ n-1 ] + F[ n-2 ]。给你两个数 n 和 m ,求前 n 项斐波那契的和对 m 求余的值。
思路:打表可推导出 S[ n ] = S[ n-1 ] + S[ n-2 ] + 1;很明显用矩阵快速幂做。构造矩阵链接:https://blog.csdn.net/HXX904/article/details/116735993?spm=1001.2014.3001.5501
AC代码:
/* 求斐波那契的前n项和对mod求余 打表可推导出s[n]=s[n-1]+s[n-2]+1; */ #include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=4; ll base[N][N]; ll tmp[N][N]; ll n,mod; void Init()//初始化构造的矩阵 { base[1][1]=0; base[1][2]=1; base[1][3]=0; base[2][1]=1; base[2][2]=1; base[2][3]=0; base[3][1]=0; base[3][2]=1; base[3][3]=1; } void mult(ll x[N][N],ll y[N][N])//矩阵相乘 { ll tmp[N][N]; for(int i=1;i<N;i++) for(int j=1;j<N;j++){ tmp[i][j]=0; for(int k=1;k<N;k++) tmp[i][j]=(tmp[i][j]+x[i][k]*y[k][j])%mod; } memcpy(x,tmp,sizeof(tmp));//复制函数 } ll fpow(ll b)//矩阵快速幂 { ll ans[N][N]; memcpy(ans,base,sizeof(base)); while(b) { if(b&1)mult(ans,base); mult(base,base); b/=2; } return (1*ans[1][2]+2*ans[2][2]+1*ans[3][2])%mod; } int main() { Init(); cin>>n>>mod; if(n==1)printf("1\n"); else if(n==2)printf("%lld\n",n%mod); else printf("%lld\n",fpow(n-3)); }