试题 算法训练 奇异的虫群

试题 算法训练 奇异的虫群

资源限制
时间限制: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;
})
  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值