HDOJ-1992的升级版..先推出递推公式(其实那时候我做1992这题没推出递推公式..只找到了规律打了个表..囧.刚才重新整理了一下得出递推公式...)..然后再用矩阵乘法求解..递推公式为:

                    T [ n ] = T [n-1]+5*T[n-2]+T[n-3]-T[n-4]

      值得再次注意的是矩阵木有交换率...最后和初值矩阵做积时一定要注意顺序...


Program:

#include<iostream>  
#include<string.h>
#include<stdio.h>
#include<map>
using namespace std;
struct node
{
int s[5][5];
}h,a,temp,T,_2M[32];
int n,m;
node Matrix_Mul(node a,node b)
{
int k,i,j;
memset(temp.s,0,sizeof(temp.s));
for (k=0;k<4;k++)
for (i=0;i<4;i++)
for (j=0;j<4;j++)
temp.s[i][j]=(temp.s[i][j]+a.s[i][k]*b.s[k][j])%m;
return temp;
}
void Output_Matrix(node a)
{
int i,j;
for (i=0;i<4;i++)
{
for (j=0;j<4;j++) printf("%d ",a.s[i][j]);
printf("\n");
}
printf("---------------------\n");
return;
}
node getmatrix(node h,int l)
{
int i,k,p;
k=1;
_2M[0]=h;
for (p=1;p<=30;p++)
{
_2M[p]=Matrix_Mul(_2M[p-1],_2M[p-1]);
k*=2;
if (k>l) break;
}
memset(T.s,0,sizeof(T.s));
for (i=0;i<4;i++) T.s[i][i]=1;
while (l)
{
while (k>l)
{
k/=2;
p--;
}
T=Matrix_Mul(T,_2M[p]);
l-=k;
}
//Output_Matrix(T);
return T;
}
int main()
{
int i;
node p;
memset(a.s,0,sizeof(a.s));
a.s[0][0]=1; a.s[1][0]=5; a.s[2][0]=11; a.s[3][0]=36;
memset(h.s,0,sizeof(h.s));
for (i=0;i<3;i++) h.s[i][i+1]=1;
h.s[3][0]=-1; h.s[3][1]=1; h.s[3][2]=5; h.s[3][3]=1;
while (~scanf("%d%d",&n,&m))
{
if (!n && !m) break;
// Output_Matrix(a);
p=Matrix_Mul(getmatrix(h,n-1),a);
// Output_Matrix(p);
printf("%d\n",p.s[0][0]);
}
return 0;
}