Description
Solution
很显然的矩阵乘法,我写的是16*16的,
听说有直接的递推式,只用4*4的矩阵;
复杂度: O(log(n)∗163)
Code
#include<cstdio>
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
typedef long long LL;
const int N=15;
int n,mo;
LL S[N+1][N+1],a[N+1][N+1],f[N+1],t[N+1][N+1];
void pre()
{
S[0][15]=1;
S[1][14]=1;
S[2][13]=1;
S[3][15]=1,S[3][12]=1;
S[4][11]=1;
S[5][10]=1;
S[6][15]=1,S[6][9]=1;
S[7][8]=1,S[7][11]=1,S[7][14]=1;
S[8][7]=1;
S[9][6]=1;
S[10][5]=1;
S[11][4]=1,S[11][7]=1;
S[12][15]=1,S[12][3]=1;
S[13][2]=1,S[13][14]=1;
S[14][1]=1,S[14][7]=1,S[14][13]=1;
S[15][0]=1;S[15][15]=1,S[15][3]=1,S[15][6]=1,S[15][12]=1;
}
void chenf()
{
fo(i,0,N)t[1][i]=0;
fo(i,0,N)
fo(j,0,N)
(t[1][i]+=f[j]*a[j][i]%mo)%=mo;
fo(i,0,N)f[i]=t[1][i];
}
void chen()
{
fo(i,0,N)fo(j,0,N)t[i][j]=0;
fo(i,0,N)
fo(j,0,N)
fo(k,0,N)(t[i][j]+=a[i][k]*a[k][j]%mo)%=mo;
fo(i,0,N)fo(j,0,N)a[i][j]=t[i][j];
}
void ksm(int n)
{
fo(i,0,N)fo(j,0,N)a[i][j]=S[i][j];
f[N]=1;fo(i,0,N-1)f[i]=0;
while(n)
{
if(n&1)chenf();
chen();n>>=1;
}
}
int main()
{
pre();
while(1)
{
scanf("%d%d",&n,&mo);
if(!n)return 0;
ksm(n);
printf("%lld\n",f[N]);
}
}