开学咯……
一本通1643&LOJ10221:
【题意】:求斐波那契数列前n项的和模m的值
【思路】:记斐波那契数列第i项为,记斐波那契数列前n项的和为,即有
我们有以下几个式子:
所以我们可以构造的矩阵如下:
至于,为什么是,是因为矩阵乘法,行列相乘
【代码】:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5;ll mod;
struct node{
ll g[N][N];
node(){
memset(g,0,sizeof(g));
}//初始化全部为0
void init(){
for(int i=1;i<4;i++)
g[i][i]=1;
}//构造一定单位矩阵
node operator * (node b){
node c;int i,j,k;
for(i=1;i<4;i++)
for(j=1;j<4;j++)
for(k=1;k<4;k++)
c.g[i][k]=(c.g[i][k]+g[i][j]*b.g[j][k])%mod;
return c;
}//定义矩阵乘法的操作
}f;int n;
node ksm(int k){
node res,tmp=f;res.init();
while (k){
if (k&1) res=res*tmp;
tmp=tmp*tmp;k>>=1;
}
return res;
}//重定义了*号后,使用起来就像使用int一样方便
inline ll answer(){
if (n==1) return 1ll;node t=ksm(n-1);//记得是ksm(n-1)哦
return (t.g[1][3]+t.g[2][3]+t.g[3][3])%mod;
}
int main(){
cin>>n>>mod;//输入
f.g[1][1]=0;f.g[1][2]=1;f.g[1][3]=0;
f.g[2][1]=1;f.g[2][2]=1;f.g[2][3]=1;
f.g[3][1]=0;f.g[3][2]=0;f.g[3][3]=1;//初始化一个矩阵
cout<<answer();
return 0;
}