hdu 2604 Queuing 遞推+矩陣快速冪
阿新 • • 發佈:2019-02-06
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=10;
int n=4,m;
struct Mat
{
int mat[N][N];
};
Mat operator * (Mat a, Mat b)
{
Mat c;
memset(c.mat, 0, sizeof(c.mat));
int i, j, k;
for(k = 0; k < n; ++k)
{
for(i = 0 ; i < n; ++i)
{
for(j = 0; j < n; ++j)
{
c.mat[i][j] += a.mat[i][k] * b.mat[k][j];
c.mat[i][j]=c.mat[i][j]%m;
}
}
}
return c;
}
Mat operator ^ (Mat a, int k)
{
Mat c;
int i, j;
for(i = 0; i < n; ++i)
for (j = 0; j < n; ++j)
c.mat[i][j] = (i == j); //初始化為單位矩陣
for(; k; k >>= 1)
{
if(k&1) c = c*a;
a = a*a;
}
return c;
}
int main()
{
int k,i,j;
while(~scanf("%d%d",&k,&m))
{
if(k==0) printf("%d\n",k);
else if(k==1 ) printf("%d\n",2%m);
else if(k==2) printf("%d\n",4%m);
else if(k==3) printf("%d\n",6%m);
else
{
Mat a,b;
memset(a.mat,0,sizeof(a.mat));
a.mat[0][0]=1;
a.mat[0][2]=1;
a.mat[0][3]=1;
a.mat[1][0]=1;
a.mat[2][1]=1;
a.mat[3][2]=1;
a=a^(k-4);
/*for(i=0; i<4; i++)
{
for(j=0; j<4; j++)
printf("%d ",a.mat[i][j]);
printf("\n");
}*/
memset(b.mat,0,sizeof(b.mat));
b.mat[0][0]=9;
b.mat[1][0]=6;
b.mat[2][0]=4;
b.mat[3][0]=2;
int ans=0;
for(i=0; i<4; i++)
{
ans=(ans+b.mat[i][0]*a.mat[0][i])%m;
//printf("%d %d %d\n",b.mat[i][0],a.mat[0][i],ans);
}
printf("%d\n",ans%m);
}
}
return 0;
}