Description
Analysis
又是一道原题==
:经典模型,状压DP,1表示该位置与该位置的下面一个位置用一个骨牌覆盖,其余状态为0,自己乱搞来判定转移合法性。
然后用矩阵乘法优化dp即可。
弄一个数组表示第i行所有状态的答案,乘法数组就是合法转移关系。
Code
#include<cstdio>
#include<cstring>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int N=16;
typedef int matrix[N][N];
int n,mo;
matrix c,f,A,B;
bool bz[]={1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1};
void mul(matrix a,matrix b)
{
memset(c,0,sizeof(c));
fo(i,0,15)
fo(j,0,15)
fo(k,0,15) (c[i][j]+=(long long)a[i][k]*b[k][j]%mo)%=mo;
}
void qmi(int n)
{
for(;n;n>>=1)
{
if(n&1==1)
{
mul(f,A);
memcpy(f,c,sizeof(c));
}
mul(A,A);
memcpy(A,c,sizeof(c));
}
}
int main()
{
fo(j,0,15)
fo(k,0,15)
if((j&k)==0 && bz[j|k]) B[j][k]=1;
for(scanf("%d %d",&n,&mo);n!=0 || mo!=0;scanf("%d %d",&n,&mo))
{
memcpy(A,B,sizeof(B));
memset(f,0,sizeof(f));
f[0][0]=1;
qmi(n);
printf("%d\n",f[0][0]);
}
return 0;
}