北京的夜晚是如此的无聊QAQ。。。把这段时间主教练找的模拟赛的题都回忆一下(虽然我做的都只有水题QAQ比如这一道)。。。
经典的状压动归,我记得当年还有一道升级版的k=12345更爽。。。
主要思路就是把状态压缩状态转移方程搞出来之后矩阵加速
懒得写搜索的后果是系数矩阵我手写了整整半个小时QAQ
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int n,m;
int ans[100005][16];
int A[26][26];
struct data
{
int a[20][20];
friend data operator * (data x,data y)
{
data ans;
memset(ans.a,0,sizeof(ans.a));
for(int i=0;i<16;i++)
{
for(int j=0;j<16;j++)
{
for(int k=0;k<16;k++)
{
ans.a[i][j]=(ans.a[i][j]+x.a[i][k]*y.a[k][j])%m;
}
}
}
return ans;
}
}B,C;
void qkpower()
{
int x=n;
memset(B.a,0,sizeof(B.a));
for(int i=0;i<16;i++) B.a[i][i]=1;
for(int i=0;i<16;i++)
{
for(int j=0;j<16;j++)
{
C.a[i][j]=A[i][j];
}
}
while(x)
{
if(x&1)
{
B=B*C;
}
x=x/2; C=C*C;
}
return ;
}
void work0()
{
ans[0][15]=1;
// for(int i=1;i<=n;i++)
// {
// ans[i][0]=ans[i-1][15];
A[0][15]=1;
// ans[i][1]=ans[i-1][14];
A[1][14]=1;
// ans[i][2]=ans[i-1][13];
A[2][13]=1;
// ans[i][3]=ans[i-1][12]+ans[i-1][15];
A[3][12]=A[3][15]=1;
// ans[i][4]=ans[i-1][11];
A[4][11]=1;
// ans[i][5]=ans[i-1][10];
A[5][10]=1;
// ans[i][6]=ans[i-1][9]+ans[i-1][15];
A[6][9]=A[6][15]=1;
// ans[i][7]=ans[i-1][8]+ans[i-1][11]+ans[i-1][14];
A[7][8]=A[7][11]=A[7][14]=1;
// ans[i][8]=ans[i-1][7];
A[8][7]=1;
// ans[i][9]=ans[i-1][6];
A[9][6]=1;
// ans[i][10]=ans[i-1][5];
A[10][5]=1;
// ans[i][11]=ans[i-1][4]+ans[i-1][7];
A[11][4]=A[11][7]=1;
// ans[i][12]=ans[i-1][3]+ans[i-1][15];
A[12][3]=A[12][15]=1;
// ans[i][13]=ans[i-1][2]+ans[i-1][14];
A[13][2]=A[13][14]=1;
// ans[i][14]=ans[i-1][1]+ans[i-1][6]+ans[i-1][13];
A[14][1]=A[14][6]=A[14][13]=1;
// ans[i][15]=ans[i-1][0]+ans[i-1][3]+ans[i-1][6]+ans[i-1][12]+ans[i-1][15];
A[15][0]=A[15][3]=A[15][6]=A[15][12]=A[15][15]=1;
// }
qkpower();
/* for(int i=0;i<=15;i++)
{
for(int j=0;j<=15;j++)
{
printf("%d ",B.a[i][j]);
}
putchar('\n');
}*/
printf("%d\n",B.a[15][15]);
return ;
}
int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%d%d",&n,&m))
{
if(n==0 && m==0)break;
work0();
}
return 0;
}