题目链接
hiho提示;里面说的很清楚了,看不懂的话就去做一做骨牌覆盖的前两道题,理解起来好理解一些;
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;
const int mod=12357;
int N;
int n,k;
struct zp
{
int arr[1<<7][1<<7];
}M;
zp jx(zp a,zp b)
{
zp res;
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
res.arr[i][j]=0;
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
for(int k=0;k<N;k++)
res.arr[i][j]=(res.arr[i][j]+a.arr[i][k]*b.arr[k][j])%mod;
return res;
}
zp jk(zp a,int b)
{
zp res;
for(int i=0;i<N;i++)
for(int j=0;j<N;j++)
res.arr[i][j]=(i==j);
while(b)
{
if(b&1)
res=jx(res,a);
a=jx(a,a);
b>>=1;
}
return res;
}
void dfs(int x,int y,int l)//得到转移的矩阵
{
if(l==k)
{
M.arr[x][y]++;
return ;
}
dfs((x<<1)+1,y<<1,l+1);//x不放
dfs(x<<1,(y<<1)+1,l+1);//x竖着放
if(l+2<=k)
dfs((x<<2)+3,(y<<2)+3,l+2);//x横着放
}
int main()
{
while(~scanf("%d%d",&k,&n))
{
if((n&1)&&(k&1))//奇数不可能有解
{
printf("0\n");
continue;
}
N=1<<k;
memset(M.arr,0,sizeof(M.arr));
dfs(0,0,0);
zp res=jk(M,n);
printf("%d\n",res.arr[N-1][N-1]%mod);
}
}