传送门:传送门
题目描述
一个数列数列f(0)=0,f(1)=1,f(2)=1,f(3)=2,f(4)=3,f(5)=5......
输入
输入整数t,表示t组测试数据
接下来t行,每行输入n(0<n<1000000000000)
接下来t行,每行输入n(0<n<1000000000000)
输出
对于每个n输出f(n)%1000007
样例输入:
2
1
3
输出
1
2
对于矩阵乘法与递推式之间的关系:
如:在斐波那契数列之中
f[i] = 1*f[i-1]+1*f[i-2] f[i-1] = 1*f[i-1] + 0*f[i-2];
即
所以
由于f[1]=1,f[0]=0,f[n]=的n次方 右上角位置的数字。记住这一结论即可。
矩阵快速幂就是普通快速幂重定义乘号即可#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL MOD=1000007;
struct mat
{
LL a[2][2];
};
mat mat_mul(mat x,mat y)
{
mat res;
memset(res.a,0,sizeof(res.a));
for(LL i=0; i<2; i++)
for(LL j=0; j<2; j++)
for(LL k=0; k<2; k++)
res.a[i][j]=(res.a[i][j]+x.a[i][k]*y.a[k][j])%MOD;
return res;
}
void mat_pow(LL n)
{
mat c,res;
c.a[0][0]=c.a[0][1]=c.a[1][0]=1;
c.a[1][1]=0;
memset(res.a,0,sizeof(res.a));
for(LL i=0; i<2; i++) res.a[i][i]=1;
while(n)
{
if(n&1) res=mat_mul(res,c);
c=mat_mul(c,c);
n=n>>1;
}
printf("%lld\n",res.a[0][1]%MOD);
}
int main()
{
LL t;
LL n;
cin>>t;
while(t--)
{
scanf("%lld",&n);
mat_pow(n);
}
return 0;
}