奇异的虫群

问题描述
  在一个奇怪的星球上驻扎着两个虫群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
 
这题实际上就是用矩阵快速幂求斐波那契数
 1 import java.util.Scanner;
 2 public class 奇异的虫群 {
 3     static long n;
 4     static final long mod=1000000007;
 5     public static void main(String[] args) {
 6          Scanner sc=new Scanner(System.in);
 7           n=sc.nextLong(); 
 8           long q[][]={{0,1},{1,1}};
 9           long a[][]={{1,1}};
10          long[][] res= matrix_power(q,n-2); //这是是矩阵的n-2次 因为当t=3 sum=3+2=f(3)+f(2) 就是算出f(2)即可 
11          long ans[][]= matrix_mutiply(a,res);//这里必须是a乘res 不能颠倒 矩阵乘法不满足交换律
12          System.out.println((ans[0][0]%mod+ans[0][1]%mod)%mod);
13     }
14     private static long[][] matrix_mutiply(long[][] a, long[][] b) {
15         long[][] res=new long[a.length][b.length];
16         for(int i=0;i<a.length;i++){
17             for(int j=0;j<b.length;j++){
18                 long temp=0;
19                 for(int k=0;k<a[0].length;k++){
20                     temp= ((temp+(a[i][k]*b[k][j])%mod))%mod;  //在矩阵乘法的过程中 对每一行乘每一列的值进行取余
21                 }
22                 res[i][j]=temp;
23             }
24         }
25         return res;
26     }
27     private static long[][] matrix_power(long[][] q, long n) {
28         long res[][]=new long[2][2];
29         for(int i=0;i<2;i++){
30             res[i][i]=1;
31         }
32         while(n>0){
33             if((n&1)==1){
34                 res = matrix_mutiply(res, q);
35             }
36             q =matrix_mutiply(q, q);
37             n>>=1;
38         }
39         return res;
40     }
41      
42 }

 

posted @ 2021-03-20 17:17  nb小歪  阅读(55)  评论(0)    收藏  举报