算法训练 奇异的虫群
时间限制: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取余数的结果
扫描二维码关注公众号,回复:
9649227 查看本文章
样例输入
10
样例输出
89
样例输入
65536
样例输出
462302286
数据规模和约定
对于50%的数据 t<=10^9
对于70%的数据 t<=10^15
对于100%的数据 t<=10^18
分析:设时刻A虫群和B虫群的数量分别为和,则根据题意有
写成矩阵形式,有
记作,其中。
#include <stdio.h>
struct Matrix
{
long long int data[2][2];
};
struct Matrix mul(struct Matrix A, struct Matrix B)
{
struct Matrix ans;
for (int i = 0; i < 2; ++i)
{
for (int j = 0; j < 2; ++j)
{
ans.data[i][j] = 0;
for (int k = 0; k < 2; ++k)
ans.data[i][j] = (ans.data[i][j] + A.data[i][k] * B.data[k][j]) % 1000000007;
ans.data[i][j] %= 1000000007;
}
}
return ans;
}
struct Matrix pow(struct Matrix A, long long int n)
{
struct Matrix ans;
ans.data[0][0] = ans.data[1][1] = 1;
ans.data[0][1] = ans.data[1][0] = 0;
struct Matrix base;
base.data[0][0] = A.data[0][0];
base.data[0][1] = A.data[0][1];
base.data[1][0] = A.data[1][0];
base.data[1][1] = A.data[1][1];
while (n)
{
if (n % 2)
ans = mul(ans, base);
base = mul(base, base);
n >>= 1;
}
return ans;
}
int main()
{
long long int t;
scanf("%lld", &t);
struct Matrix A;
A.data[0][0] = A.data[0][1] = A.data[1][0] = 1;
A.data[1][1] = 0;
struct Matrix pow_A = pow(A, t - 1);
long long int p = (pow_A.data[0][0] + pow_A.data[0][1]) % 1000000007;
printf("%lld", p);
return 0;
}