试题 算法训练 奇异的虫群
资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
在一个奇怪的星球上驻扎着两个虫群A和B,它们用奇怪的方式繁殖着,在t+1时刻A虫群的数量等于t时刻A虫群和B虫群数量之和,t+1时刻B虫群的数量等于t时刻A虫群的数量。由于星际空间的时间维度很广阔,所以t可能很大。OverMind 想知道在t时刻A虫群的数量对 p = 1,000,000,007.取余数的结果。当t=1时 A种群和B种群的数量均为1。
输入格式
测试数据包含一个整数t,代表繁殖的时间。
输出格式
输出一行,包含一个整数,表示对p取余数的结果
样例输入
10
样例输出
89
样例输入
65536
样例输出
462302286
数据规模和约定
对于50%的数据 t<=10^9
对于70%的数据 t<=10^15
对于100%的数据 t<=10^18
分析
考察了矩阵快速幂
通过观察不难发现这是一个斐波拉契数列这里引用其他dalao的图片
可以将斐波拉契写成矩阵形式
通过递归可得到
有
于是问题变成了求这个矩阵的n-1次方,这里就用到了快速幂的方法
快速幂可看
快速幂java c语言实现
有点不同的是刚开始的1变成了一个单位矩阵 原理是一样的 同时也考察到了矩阵相乘 相信学了线代的朋友应该知道了
ac代码
代码如下:
#include<stdio.h>
#define N 1000000007
void xiangc(long long int a[2][2],long long int b[2][2])
{
long long int i,j,z,c[2][2]={0};
for(i=0;i<2;i++)
{
for(j=0;j<2;j++)
{
for(z=0;z<2;z++)
{
c[i][j]+=a[i][z]*b[z][j];
}
}
}
for(i=0;i<2;i++)
{
for(j=0;j<2;j++)
{
a[i][j]=c[i][j];
}
}
}
void quyu(long long int a[2][2])
{
int i,j;
for(i=0;i<2;i++)
{
for(j=0;j<2;j++)
{
a[i][j]%=N;
}
}
}
int main()
{
long long int t,i,j;
scanf("%lld",&t);
t-=1;
long long int a[2][2],b[2][2];
a[0][0]=1;
a[0][1]=0;
a[1][0]=0;
a[1][1]=1;
b[0][0]=1;
b[0][1]=1;
b[1][0]=1;
b[1][1]=0;
while(t>0)
{
if(t%2==1)
{
xiangc(a,b);
quyu(a);
}
t/=2;
xiangc(b,b);
quyu(b);
}
printf("%lld",(a[0][0]+a[1][0])%N);
return 0;
})