Problem Description
给你一个4×N的矩阵,你可以填1×2的矩阵 or 2×1的矩阵,问你填满有多少种方案,需要取mod。
思路:
poj 2411的基础上加了个矩阵快速幂
#include<cstdio>
#include<cstring>
using namespace std;
struct node
{
long long a[16][16];
};
node c;
int n, mod;
void dfs(int l, int now, int pre)
{
if(l > 4) return;
if(l == 4)
{
c.a[pre][now]++;
return ;
}
dfs(l + 2, (now<<2)|3, (pre<<2)|3);
dfs(l + 1, now<<1, (pre<<1)|1);
dfs(l + 1, (now<<1)|1, pre<<1);
}
node mul(node x, node y)//矩阵相乘
{
node ans;
int i, j, k;
for(i = 0; i < 16; i++)
{
for(j = 0; j < 16; j++)
{
ans.a[i][j] = 0;
for(k = 0; k < 16; k++)
{
ans.a[i][j] += x.a[i][k] * y.a[j][k];
ans.a[i][j] %= mod;
}
}
}
return ans;
}
node sm(node x, int m)//矩阵快速幂
{
node ans;
memset(ans.a, 0, sizeof(ans.a));
for(int i = 0; i < 16; i++) ans.a[i][i] = 1;
while(m)
{
if(m & 1) ans = mul(ans, x);
x = mul(x, x);
m = m>>1;
}
return ans;
}
int main()
{
while(~scanf("%d %d", &n, &mod))
{
if(!n && !mod) break;
if(mod == 1) {printf("0\n"); continue;}
memset(c.a, 0, sizeof(c.a));
dfs(0, 0, 0);
node ans = sm(c, n);
printf("%lld\n", ans.a[15][15]);
}
return 0;
}