题目链接:hdu1757
思路:首先,矩阵乘法具有结合律,即矩阵A*B*C = A*(B*C)
本题 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10)
构造的矩阵如下:
A B
| f(10) | | a0 a1 a2 ... a8 a9 | | f(9) |
| f(9) | | 1 0 0 ... 0 0 | | f(8) |
| f(8) | | 0 1 0 ... 0 0 | | f(7) |
|..........| = | ... ... ... ... ... ... | * | .... |
| f(2) | | 0 0 0 ... 0 0 | | f(1) |
| f(1) | | 0 0 0 ... 1 0 | | f(0) |
k = 10 时,f(10) = A*B
k = 11时,f(11) = A*A*B
k = 12时,f(12) = A*A*A*B
……
由此可以找到规律:k = x 时,f(x) = A*A*A*………A*A*B
接着用矩阵乘法快速幂的方法求解
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cstdlib>
using namespace std;
int k,mod;
struct node
{
int map[10][10];
}unit,s;
node Mul(node a,node b)
{
node c;
int i,j,k;
for(i = 0; i < 10; i ++)
for(j = 0; j < 10; j ++)
{
c.map[i][j] = 0;
for(k = 0;k < 10; k ++)
c.map[i][j] += (a.map[i][k] * b.map[k][j])%mod;
c.map[i][j] %= mod;
}
return c;
}
void Matrix()
{
while(k)
{
if(k&1) unit = Mul(unit,s);
k >>= 1;
s = Mul(s,s);
}
int ans = 0;
for(int j = 0; j < 10; j ++)
ans += unit.map[0][j]*(9-j), ans %= mod;
printf("%d\n",ans);
}
int main()
{
int i,j;
while(~scanf("%d%d",&k,&mod))
{
memset(unit.map,0,sizeof(unit.map));
memset(s.map,0,sizeof(s.map));
for(i = 0; i < 10; i ++)
unit.map[i][i] = 1;
for(i = 1; i < 10; i ++)
s.map[i][i-1] = 1;
for(j = 0; j < 10; j ++)
scanf("%d",&s.map[0][j]);
if(k < 10)
{
printf("%d\n",k%mod);
continue;
}
k -= 9;
Matrix();
}
return 0;
}