Description
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);
And ai(0<=i<=9) can only be 0 or 1 .
Now, I will give a0 ~ a9 and two positive integers k and m ,and could you help Lele to caculate f(k)%m.
Input
In each case, there will be two lines.
In the first line , there are two positive integers k and m. ( k<2*10^9 , m < 10^5 )
In the second line , there are ten integers represent a0 ~ a9.
Output
Sample Input
10 9999 1 1 1 1 1 1 1 1 1 1 20 500 1 0 1 0 1 0 1 0 1 0
Sample Output
45 104
题意
一个分段函数f(x)。
当 x < 10 时,f(x) = x。
当 x >= 10 时,f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10)。
并且 ai(0<=i<=9) 只能是 0 或 1。
现在给出 a0 ~ a9 ,k 和 m ,输出f(k) % m( k < 2 * 10^9 , m < 10^5 )。
分析
看 k 的范围知道 k 很大,直接跑 o(n) 的循环肯定会 T 掉,所以想到用矩阵来加速,构造的矩阵A为10*10矩阵,如下
0 1 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 1
a9 a8 a7 a6 a5 a4 a3 a2 a1 a0
所求问题可转化为求由f(0),f(1),...,f(9)构成的列矩阵 F 与 A 的乘法,只需乘 k-9 次即可。
10 * 10 的矩阵看着是真头疼,Orz......
AC代码如下
#include<cstdio>
#include<cstring>
#define N 10
using namespace std;
int k,m;
struct S
{
int m[N][N];
};
S matrix_multiplication(S a,S b)
{
S c;
memset(c.m,0,sizeof(c.m));
for(int i = 0 ; i < N ; i++)
for(int j = 0 ; j < N ; j++)
{
for(int k = 0 ; k < N ; k++)
c.m[i][j] += (a.m[i][k] * b.m[k][j]) % m;
c.m[i][j] %= m;
}
return c;
}
S quick_power(S a,int x)
{
if(x == 1) return a;
else if(x & 1) return matrix_multiplication(quick_power(a,x-1),a);
else
{
S c = quick_power(a,x/2);
return matrix_multiplication(c,c);
}
}
int main()
{
S a;
while(~scanf("%d%d",&k,&m))
{
for(int i = N-1 ; i >= 0; i--)
scanf("%d",&a.m[9][i]);
if(k < 10)
{
printf("%d\n",k % m);
continue;
}
for(int i = 0 ; i < N-1 ; i++)
for(int j = 0 ; j < N ; j++)
{
if(j == i + 1) a.m[i][j] = 1;
else a.m[i][j] = 0;
}
S res = quick_power(a,k-9);
int ans = 0;
for(int i = 0 ; i < N ; i++)
ans += (res.m[9][i] * i) % m;
printf("%d\n",ans%m);
}
return 0;
}
本文介绍了一种使用矩阵快速幂的方法解决大规模递推数列问题的技术。针对给定的分段递推函数,通过构建特定的10×10矩阵并利用快速幂运算,可以有效地计算出f(k)%m的结果,即使k的值非常大也能在合理的时间内得出答案。
975

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



