题目:http://acm.hdu.edu.cn/showproblem.php?pid=1757
题目描述:函数f(x)满足如下条件:
x
<
10
时
,
f
(
x
)
=
x
;
x < 10时,f(x)=x;
x<10时,f(x)=x;
x
>
=
10
时
,
f
(
x
)
=
a
0
∗
f
(
x
−
1
)
+
a
1
∗
f
(
x
−
2
)
+
.
.
.
+
a
9
∗
f
(
x
−
10
)
x >= 10时, f(x)=a_0*f(x-1)+ a_1 * f(x-2) + ... + a_9 * f_(x-10)
x>=10时,f(x)=a0∗f(x−1)+a1∗f(x−2)+...+a9∗f(x−10)
a
i
(
0
<
=
i
<
=
9
)
,
a
i
只
能
为
0
或
1
a_i(0 <= i<=9), a_i只能为0或1
ai(0<=i<=9),ai只能为0或1
输入k和m,输出 f(k)%m
解题方法:矩阵快速幂
code:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cstdio>
using namespace std;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e5 + 7;
const int N = 11;
int num[N][N];
int A[N][N];
int ans[N][N];
int temp[N][N];
int mod;
void init()
{
memset(num, 0, sizeof(num));
memset(A, 0, sizeof(A));
}
void multi(int a[][N], int b[][N])
{
memset(temp, 0, sizeof(temp));
for(int i = 0; i < N; i++)
for(int j = 0; j < N; j++)
for(int k = 0; k < N; k++)
temp[i][j] = (temp[i][j] + a[i][k] * b[k][j]) % mod;
for(int i = 0; i < N; i++)
for(int j = 0; j < N; j++)
a[i][j] = temp[i][j];
}
void MatPow(int a[][N], int n)
{
memset(ans, 0, sizeof(ans));
for(int i = 0; i < N; i++) ans[i][i] = 1;
while(n)
{
if(n & 1)
multi(ans, a);
multi(a, a);
n >>= 1;
}
}
int main()
{
int k;
while(~scanf("%d %d", &k, &mod))
{
init();
for(int i = 0; i < 10; i++)
scanf("%d", &A[0][i]);
if(k < 10) printf("%d\n", k%mod);
else
{
for(int i = 0; i < 10; i++) num[i][0] = 9 - i;
for(int i = 1; i < 10; i++) A[i][i - 1]= 1;
MatPow(A, k - 9);
int res = 0;
for(int i = 0; i < 10; i++)
{
res += (ans[0][i] * num[i][0]) % mod;
res = res % mod;
}
cout << res << endl;
}
}
return 0;
}