链接
题意
当i < 10时,f(i) = i;当i >= 10时,f(i) = f(i-1) * a0 + f(i-2) * a1 + … + f(i-10) * a9。
a0到a9都是1或0,给出a0到a9,求f(k)。
题解
一道比较容易的矩阵构造,新生成的那项f(new)需要之前的10项乘系数求和,显然需要一个向量(f(new-1), f(new-2), …, f(new-10))和向量T(1, 1, 1, …, 1)相乘,之后又需要保留f(new-1)到f(new-9),所以还是相对容易构造的:
a0 1
a1 0 1
a2 0 0 1
a3 0 0 0 1
a4 0 0 0 0 1
a5 0 0 0 0 0 1
a6 0 0 0 0 0 0 1
a7 0 0 0 0 0 0 0 1
a8 0 0 0 0 0 0 0 0 1
a9 0 0 0 0 0 0 0 0 0
这就是转移矩阵。
之后求快速幂即可。
代码
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long lint;
int mod;
struct matrix
{
int a[10][10], n;
void clear() { memset(a, 0, sizeof(a)); }
matrix(int k, int type)
{
n = k, clear();
if(type) for(int i = 0; i < n; i++)
a[i][i] = 1;
}
matrix() { n = 2, clear(); a[0][0] = a[0][1] = a[1][0] = 1, a[1][1] = 0; }
matrix operator* (const matrix& b) const
{
matrix o = matrix(n, 0);
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
for(int k = 0; k < n; k++)
{
o.a[i][j] += ((lint)a[i][k] * b.a[k][j]) % mod;
o.a[i][j] %= mod;
}
return o;
}
friend matrix operator^ (matrix tmp, int k)
{
matrix o = matrix(tmp.n, 1);
while(k)
{
if(k & 1) o = o * tmp;
tmp = tmp * tmp;
k >>= 1;
}
return o;
}
};
matrix getKthsum(const matrix& b, int k)
{
matrix tmp = matrix(b.n << 1, 0);
for(int i = 0; i < b.n; i++)
for(int j = 0; j < b.n; j++)
tmp.a[i][j] = b.a[i][j];
for(int i = 0; i < b.n; i++)
{
tmp.a[i][b.n + i] = 1;
tmp.a[b.n + i][b.n + i] = 1;
}
tmp = tmp^(k+1);
matrix o = matrix(b.n, 0);
for(int i = 0; i < b.n; i++)
for(int j = 0; j < b.n; j++)
o.a[i][j] = tmp.a[i][b.n + j];
for(int i = 0; i < b.n; i++)
o.a[i][i] = (o.a[i][i] + mod - 1) % mod;
return o;
}
int main()
{
int k, m;
while(cin >> k >> m)
{
mod = m;
matrix B = matrix(10, 0), A = matrix(10, 0);
for(int i = 0; i < 10; i++) B.a[0][i] = 9 - i;
for(int i = 0; i < 10; i++) scanf("%d", &A.a[i][0]);
for(int i = 1; i < 10; i++) A.a[i-1][i] = 1;
if(k < 10) printf("%d\n", k % mod);
else
{
matrix ans = matrix(10, 0);
ans = B * (A ^ (k - 9));
printf("%d\n", ans.a[0][0]);
}
}
return 0;
}
本文详细解析了HDU1757题目,介绍了一种使用矩阵快速幂的方法来解决该递推数列问题。通过构造特定的转移矩阵,并利用快速幂算法高效计算出目标项f(k)。
478

被折叠的 条评论
为什么被折叠?



