【题目】
Problem E: 骨牌覆盖1
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 363 Solved: 175
[Submit][Status][Web Board]
Description
我们有一个2xN的长条形棋盘,然后用1x2的骨牌去覆盖整个棋盘。对于这个棋盘,一共有多少种不同的覆盖方法呢?
Input
输入n,n<=100000
Output
覆盖方案总数对19999997取余
Sample Input
1 2
Sample Output
1 2
【题解】
求斐波那契数列的矩阵快速幂运用。
【代码】
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod =19999997;
ll n;
struct p{
ll mapp[2][2];
} ans,base;
p mult(p a,p b)
{
p c;
int i,j,k;
memset(c.mapp,0,sizeof(c.mapp));
for(i=0; i<2; i++)
for(j=0; j<2; j++)
for(k=0; k<2; k++)
c.mapp[i][j]=(c.mapp[i][j]+a.mapp[i][k]*b.mapp[k][j])%mod;
return c;
}
ll pow(ll n)
{
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
{
if(i==1&&j==1)
base.mapp[i][j]=0;
else
base.mapp[i][j]=1;
if(i==j)
ans.mapp[i][j]=1;
else
ans.mapp[i][j]=0;
}
while(n)
{
if(n&1) ans=mult(ans,base);
base=mult(base,base);
n>>=1;
}
return ans.mapp[0][1]%mod;
}
int main()
{
while(~scanf("%lld",&n))
printf("%lld\n",pow(n+1));
return 0;
}