A Simple Math Problem
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 6573 Accepted Submission(s): 4033
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.
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.
10 9999 1 1 1 1 1 1 1 1 1 1 20 500 1 0 1 0 1 0 1 0 1 0
45 104
矩阵快速幂解决
第一步,构造矩阵:
(
a
0
a
1
a
2
a
3
a
4
a
5
a
6
a
7
a
8
a
9
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
0
)
×
(
f
x
−
1
f
x
−
2
f
x
−
3
f
x
−
4
f
x
−
5
f
x
−
6
f
x
−
7
f
x
−
8
f
x
−
9
f
x
−
10
)
=
(
f
x
f
x
−
1
f
x
−
2
f
x
−
3
f
x
−
4
f
x
−
5
f
x
−
6
f
x
−
7
f
x
−
8
f
x
−
9
)
\begin{pmatrix} a_0 & a_1 & a_2 & a_3 & a_4& a_5 & a_6& a_7 & a_8&a_9\\ 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 &0 \\ \end{pmatrix}\times \begin{pmatrix}f_{x-1}\\f_{x-2}\\f_{x-3}\\f_{x-4}\\f_{x-5}\\f_{x-6}\\f_{x-7}\\f_{x-8}\\f_{x-9}\\f_{x-10}\end{pmatrix} =\begin{pmatrix}f_{x}\\ f_{x-1}\\f_{x-2}\\f_{x-3}\\f_{x-4}\\f_{x-5}\\f_{x-6}\\f_{x-7}\\f_{x-8}\\f_{x-9}\end{pmatrix}
⎝⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎛a0100000000a1010000000a2001000000a3000100000a4000010000a5000001000a6000000100a7000000010a8000000001a9000000000⎠⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎞×⎝⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎛fx−1fx−2fx−3fx−4fx−5fx−6fx−7fx−8fx−9fx−10⎠⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎞=⎝⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎛fxfx−1fx−2fx−3fx−4fx−5fx−6fx−7fx−8fx−9⎠⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎞
然后利用矩阵快速幂求得:
(
a
0
a
1
a
2
a
3
a
4
a
5
a
6
a
7
a
8
a
9
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
0
)
n
−
9
×
(
f
9
f
8
f
7
f
6
f
5
f
4
f
3
f
2
f
1
f
0
)
=
(
f
n
f
n
−
1
f
n
−
2
f
n
−
3
f
n
−
4
f
n
−
5
f
n
−
6
f
n
−
7
f
n
−
8
f
n
−
9
)
\begin{pmatrix} a_0 & a_1 & a_2 & a_3 & a_4& a_5 & a_6& a_7 & a_8&a_9\\ 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 &0 \\ \end{pmatrix}^{n-9}\times \begin{pmatrix}f_{9}\\f_{8}\\f_{7}\\f_{6}\\f_{5}\\f_{4}\\f_{3}\\f_{2}\\f_{1}\\f_{0}\end{pmatrix} =\begin{pmatrix}f_{n}\\ f_{n-1}\\f_{n-2}\\f_{n-3}\\f_{n-4}\\f_{n-5}\\f_{n-6}\\f_{n-7}\\f_{n-8}\\f_{n-9}\end{pmatrix}
⎝⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎛a0100000000a1010000000a2001000000a3000100000a4000010000a5000001000a6000000100a7000000010a8000000001a9000000000⎠⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎞n−9×⎝⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎛f9f8f7f6f5f4f3f2f1f0⎠⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎞=⎝⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎜⎛fnfn−1fn−2fn−3fn−4fn−5fn−6fn−7fn−8fn−9⎠⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎟⎞
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 13;
struct mat{ll m[MAXN][MAXN]; };
ll n,MOD;
ll N,k,b_n=0;
ll C[MAXN],h[MAXN];
mat mul(mat a,mat b)//矩阵乘法
{
mat tmp;
for(int i=1;i<=N;i++)
for(int j=1;j<=N;j++)
{
tmp.m[i][j]=0;
for(int k=1;k<=N;k++)
tmp.m[i][j]=(tmp.m[i][j]+a.m[i][k]*b.m[k][j]+MOD)%MOD;
}
return tmp;
}
mat pow_mod(mat a,ll n)
{
mat ans;
for(int i=1;i<=N;i++)//构造单位矩阵
for(int j=1;j<=N;j++)
ans.m[i][j]=(i==j);
while(n)//矩阵快速幂
{
if(n&1) ans=mul(ans,a);
a=mul(a,a);
n>>=1;
}
return ans;
}
void init(mat &res,mat &H)//构造矩阵
{
for(int i=1;i<=N;i++)
res.m[1][i]=C[i];
res.m[1][N]=b_n;
for(int i=2;i<=N;i++)
for(int j=1;j<=N;j++)
res.m[i][j]=(i==j+1);
res.m[N][N-1] = 0;
res.m[N][N] = 1;
for(int i=1;i<=N;i++)
{
H.m[i][1]=h[N-i];
for(int j=2;j<=N;j++)
H.m[i][j]=0;
}
H.m[N][1]=1;
}
void slove(ll k,ll n)
{
mat res,H;
init(res,H);
res = pow_mod(res,n-k+1);
res = mul(res,H);
ll ans=res.m[1][1];
printf("%lld\n",ans%MOD);
}
int main()
{
k=10; N=11;
for(int i=1;i<=k;i++) h[i]=i-1;
while(~scanf("%lld %lld",&n,&MOD))//f(n)%MOD;,我更习惯这样写
{
for(int i=1;i<=k;i++)
scanf("%lld",&C[i]);//第一次没有加&,找了好久。。。我好傻
if(n<10)
{
printf("%d\n",n);
continue;
}
slove(k,n);
}
return 0;
}