算法训练 奇异的虫群
问题描述
在一个奇怪的星球上驻扎着两个虫群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
对于70%的数据 t<=10^15
对于100%的数据 t<=10^18
/**
*
*/
package com.xingbing.lanqiao;
import java.util.Scanner;
/**
* @author
* @data
* @description
*/
public class 奇异的虫群 {
public static long a[][];
public static long p = 1000000007;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
long n = in.nextLong();
a = new long[2][2];
a[0][0] = a[0][1] = a[1][0] = 1;
a[1][1] = 0;
solve(n);
}
public static void solve(long n){
//构建一个单位矩阵
long ans[][] = new long[2][2];
for(int i=0;i<ans.length;i++){
ans[i][i] = 1;
}
while(n!=0){
if((n&1)==1){
ans = multi(ans, a);
}
a = multi(a,a);
n>>=1;
}
System.out.println(ans[0][0]);
}
//矩阵相乘
public static long [][] multi(long a[][], long b[][]){
long temp[][] = new long[2][2];
for(int i=0;i<2;i++){
for(int j=0;j<2;j++){
for(int k=0;k<2;k++){
temp[i][j] += (a[i][k]*b[k][j])%p;
temp[i][j]%=p;
}
}
}
return temp;
}
}
浙公网安备 33010602011771号