坐标系
描述
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
就是推一下公式
f[n]=f[n-2]+2*f[n-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;
}