Java - Nuc - 郭姐散步 ( 矩阵快速幂 )

描述

The first lady of our team is GuoJie, GuoJie likes walking very much.

Today GuoJie walks from the original point (0, 0), everytime he(may be she?) can go up or left or right a step.

But she can't go back the point where she have visited.

For example, if he goes up a step, she will be at (1, 0) and she never comes back the point.

Now, if she can walk n(n <= 1000000) steps, can you find how many ways she can walk? the result mod 1e9 + 7. 

输入
There will be T (T <= 100) cases, each case will input a n.
输出
For each group of input integers you should output how many ways GuoJie can walk in one line, and with one line of output for each line in input.
样例输入
1
2
样例输出
7
提示
n<=0 输出0
来源

Json



由分析可知,每一步的下一步可以有两种或者三种选择,有两种选择的步其下一步的选择数为2+3,有三种选择的步其下一步为2+2+3.

所以设an为2的个数,bn 为3的个数,ans即为2*an+3*bn 





import java.util.Scanner;
public class Main{
	final static int Mod = (int)1e9+7;
	public static void main(String[]args){
		Scanner sc = new Scanner(System.in);
		int T = sc.nextInt();
		for(int i=1 ; i<=T ;i++){
			int n = sc.nextInt();
			
			if(n<0||n==0){
				System.out.println(0);
			}else if(n==1){
				System.out.println(3);
			}else{
				long[][]a = new long[2][1];
				a[0][0] = 0;
				a[1][0] = 1;
				long[][]c = new long[2][2];
				c[0][0] = 1;
				c[0][1] = 2;
				c[1][0] = 1;
				c[1][1] = 1;
				
				long[][]x = new long[2][1];
				x = Multiply_Matrix(Matrix_Ksm(c,n-1),a);
				long times = (x[0][0]*2%Mod+x[1][0]*3%Mod)%Mod;
				System.out.println(times);	
			}
			
		}
	}
	public static long[][] Multiply_Matrix(long[][]a ,long[][]b){		//矩阵乘法
		long[][]c = new long [a.length][b[0].length];
		for(int i=0 ;i<a.length ;i++){
			for(int j=0 ;j<b[0].length ;j++){
				long temp = 0;
				for(int x=0 ; x<b.length ;x++){
					temp = (temp+((a[i][x]%Mod)*(b[x][j]%Mod))%Mod)%Mod;
				}
				c[i][j] = temp;
			}
		}
		return c;
	} 
	public static long[][] Matrix_Ksm(long[][]a ,int k){		//矩阵快速幂
		long[][]d = new long[a.length][a[0].length];
		if(k==1){
			return a;
		}
		else if(k==2){
			return Multiply_Matrix(a,a);
		}
		else if(k%2==0){
			d = Matrix_Ksm(Multiply_Matrix(a,a),k/2);
			return d;
		}
		else{
			d = Matrix_Ksm(Multiply_Matrix(a,a),k/2);
			return Multiply_Matrix(d,a);
		}
	}
} 


有算法优化请评论

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值