函数满足——If x < 10 f(x) = x.
If x >= 10 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10);
要你求f(k) % mod;
3.解题思路:
我开始想的就是递推,果断地T了,然后。。。大半天最后看discuss才发现是矩阵快速幂。然后总结完二分再来总结快速幂,突然发现二者其实是存在联系的,就是把连乘每次折半地运算,尤其对于矩阵幂运算,大大加速了计算。
言归正传,网上盗了一张递推图
这样就把问题转化为求矩阵的n-9次幂
4.AC代码:
#include
#define INF 0x3f3f3f3f
#define maxn 20010
#define N 10
#define eps 1e-6
#define pi acos(-1.0)
#define e exp(1.0)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
int a[N], f[N], k, mod;
struct Matrix
{
ll mat[N][N];
Matrix operator*(const Matrix &m) const
{
Matrix tmp;
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
{
tmp.mat[i][j] = 0;
for (int k = 0; k < N; k++)
{
tmp.mat[i][j] += mat[i][k] * m.mat[k][j] % mod;
tmp.mat[i][j] %= mod;
}
}
return tmp;
}
};
ll Pow(Matrix &m, int k)
{
Matrix ans;
memset(ans.mat, 0, sizeof(ans.mat));
for (int i = 0; i < N; i++)
ans.mat[i][i] = 1;
k -= 9;
while (k)
{
if (k & 1)
ans = ans * m;
k >>= 1;
m = m * m;
}
ll sum = 0;
for (int i = 0; i < N; i++)
sum += ans.mat[0][i] * f[N - i - 1] % mod;
sum %= mod;
return sum;
}
void init(Matrix &m)
{
memset(m.mat, 0, sizeof(m.mat));
for (int i = 0; i < N; i++)
m.mat[0][i] = a[i];
for (int i = 0; i < N - 1; i++)
m.mat[i + 1][i] = 1;
for (int i = 0; i < N; i++)
f[i] = i;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
long _begin_time = clock();
#endif
Matrix m;
while (~scanf("%d%d", &k, &mod))
{
for (int i = 0; i < N; i++)
scanf("%d", &a[i]);
init(m);
if (k < 10)
printf("%d\n", k % mod);
else
printf("%lld\n", Pow(m, k));
}
#ifndef ONLINE_JUDGE
long _end_time = clock();
printf("time = %ld ms.", _end_time - _begin_time);
#endif
return 0;
}