1. 程式人生 > >【2018/10/11】T2

【2018/10/11】T2

座標系

描述

Tom 者表也,數學者景也,表動則景隨矣。

Tom 不喜歡數學,可數學卻待 Tom 如初戀,Tom 睡覺的時候也不放過。

Tom 的夢境中出現了一個平面直角座標系,自原點,向四方無限延伸。

Tom 在座標系的原點,他可以向上、向左或者向右走。他可以走 n 步,但不能經過相同 的點。

Tom 想知道他有多少種走法

輸入

輸入檔案僅第一行一個正整數 n,表示 Tom 可以走的步數。

輸出

輸出檔案共一行,輸出一個正整數,表示答案(對 10^9+7 取模)。

樣例輸入

2

樣例輸出

7

【輸入輸出樣例 1 說明】

從(0,0)出發走 2 步,共 7 種走法:

(0,0)->(0,1)->(0,2)
(0,0)->(0,1)->(1,1)
(0,0)->(0,1)->(-1,1)
(0,0)->(1,0)->(2,0)
(0,0)->(1,0)->(1,1)
(0,0)->(-1,0)->(-2,0)
(0,0)->(-1,0)->(-1,1)
測試點編號 n
1~2 n<=10
3~4 n<=100
5~6 n<=1000
7~8 n<=10^6
9~10 n<=10^9

 分析

水題*2

就是推一下公式,然後用矩陣快速冪來實現即可

然後我忘了開long long,傻逼了

程式碼

#include<bits/stdc++.h>
#define ll long long
#define in read()
#define P 1000000007
using namespace std;
inline int read(){
	char ch;int f=1,res=0;
	while((ch=getchar())<'0'||ch>'9') if(ch=='-') f=-1;
	while(ch>='0'&&ch<='9'){
		res=(res<<3)+(res<<1)+ch-'0';
		ch=getchar();
	}
	return f==1?res:-res;	
}
struct matrix{
	int a[4][4];
	matrix(int t=0){
		memset(a,0,sizeof(a));
		for(int i=1;i<=2;++i) a[i][i]=t;
	}
	friend inline matrix operator * (const matrix &a,const matrix &b){
		matrix c(0);
		for(int i=1;i<=2;++i)
			for(int j=1;j<=2;++j)
				for(int k=1;k<=2;++k)
					c.a[i][j]=(c.a[i][j]+1ll*a.a[i][k]%P*b.a[k][j]%P)%P;
		return c;
	}
	friend inline matrix operator ^(matrix a,int b){
		matrix c(1);
		while(b){
			if(b&1) c=c*a;
			a=a*a;
			b>>=1;
		}
		return c;
	}
}A,B;
int n;
int main(){
	n=in;
	if(n==1) {	printf("3");return 0;}
	if(n==2) {	printf("7");return 0;}
	A.a[1][1]=7,A.a[1][2]=3;
	B.a[1][1]=2;B.a[1][2]=1;B.a[2][1]=1;B.a[2][2]=0;
	B=B^(n-2);
	A=A*B;
	printf("%d",A.a[1][1]);
	return 0;
}