Description
Lele now is thinking about a simple function f(x).
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.
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
The problem contains mutiple test cases.Please process to the end of file.
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.
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
For each case, output f(k) % m in one line.
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
题意很简单,公式给出来了,不过找循环节的话不太靠谱,应该可以,可是没去细想。这道题的公式是类似斐波那契数列的,所以用矩阵快速幂妥妥可以解出来。
本题用矩阵求解公式如下:
这个公式是由以下公式推导而来的:
只要先求出后面的方阵的幂,然后再求fn即可。
只要是类似斐波那契的数列都可以用上面的公式变形求得。
至于矩阵可以写一个结构体或者类,然后重载一下*和%就可以直接套用快速幂的模板了,本题的快速幂是位运算模式的,所以就直接重载掉^了
代码:
#include<iostream>
using namespace std;
int M;
class mat
{
public:
int num[10][10];
void sete()
{
for (int i = 0; i<10; i++)
for (int j = 0; j<10; j++)
{
if (i == j) num[i][j] = 1;
else num[i][j] = 0;
}
}
void setone(int *a)
{
for (int i = 0; i<10; i++)
num[0][i] = a[i];
for (int i = 1; i<10; i++)
for (int j = 0; j<10; j++)
{
if (i - 1 == j) num[i][j] = 1;
else num[i][j] = 0;
}
}
mat operator * (const mat& ano)
{
mat ans;
for (int i = 0; i<10; i++)
{
for (int j = 0; j<10; j++)
{
ans.num[i][j]=0;
for (int k = 0; k<10; k++)
ans.num[i][j] += (((this->num)[i][k])*((ano.num)[k][j])%M);
ans.num[i][j]=ans.num[i][j]%M;
}
}
return ans;
}
mat operator %(int m)
{
mat ans;
for (int i = 0; i<10; i++)
for (int j = 0; j<10; j++)
ans.num[i][j] = this->num[i][j] % m;
return ans;
}
mat operator ^(int b)
{
mat a = *this;
mat res;
res.sete();
while (b) {
if (b & 1)
res = res * a;
a = a * a;
b >>= 1;
}
return res;
}
};
int basenum[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int main()
{
int a[10];
int k;
while (cin >> k >> M)
{
for (int i = 0; i<10; i++)
cin >> a[i];
if (k<10)
{
cout << basenum[k] % M << endl;
continue;
}
mat one;
one.setone(a);
mat two;
two = one^(k-9);
int ans = 0;
for (int i = 0; i < 10; i++)
ans = (ans + two.num[0][i]*(9-i)) % M;
cout << ans % M << endl;
}
return 0;
}