蓝桥杯VIP试题 算法训练 奇异的虫群

试题 算法训练 奇异的虫群

资源限制
时间限制: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

思路:本题如果用常规的做法,输入时间一直遍历,时间到了之后对1000000007取余输出,那只有一个结果,就是数字太大导致超时。
那么仔细看看这道题发现他的规律与斐波那契数列一样,所以我们可以用快速幂矩阵的方法对其求解,可以大大减少运行的时间。我们看看如何用矩阵求解,斐波那契数列公式为Fn=Fn-1+Fn-2,如何用Fn-1、Fn-2乘以一个矩阵得到Fn,我们看看这个:在这里插入图片描述
上面可以定义一个矩阵为{1,1,1,0},每次相乘可得下一次的结果,为了减少时间,必须记录每次计算的值,比如2*2=4为四次幂,也相当于计算了四次,比如当时间为9,即计算第一次变成平方,记录下来,二次计算为四次方,三次为八次方,再乘以原来的一次即为九次,原本需要计算八次的四次计算就可以了。而在这当中需要考虑偶数和奇数的情况,这与另外一个题矩阵乘方的做法一样(我的博客中这篇文章进行了说明,这里就不多说了),如果为2的幂方的可以直接进行计算,不是2的幂方的就得另外做考虑,所以此题用矩阵的快速幂做法可以解决常规做法运行超时的问题,也能让我们加深对这种方法的理解。

代码如下:

#include<iostream>
#include<cstring>
using namespace std;
void ks(long long a1[2][2],long long b1[2][2]){
	long long c[2][2];
	int i,j,k;
	memset(c,0,sizeof(c));
	for(i=0;i<2;i++){
		for(j=0;j<2;j++){
			for(k=0;k<2;k++){
				c[i][j]+=(a1[i][k]*b1[k][j])%1000000007;
			}
		}
	}
	memcpy(a1,c,sizeof(c));
}
int main(){
	long long t,a[2][2]={1,1,1,0},b[2][2]={1,0,0,1};
	cin>>t;
	while(t>0){
		if(t%2==1){
			ks(b,a);
		}
		ks(a,a);
		t/=2;    //有些做法将t%2==1为n&1,t/2为t>>=1与本题中计算结果一样
	}
	cout<<b[0][0]%1000000007;
}
发布了51 篇原创文章 · 获赞 47 · 访问量 1942

猜你喜欢

转载自blog.csdn.net/weixin_45269353/article/details/104576522