0
点赞
收藏
分享

微信扫一扫

HDU1757 A Simple Math Problem——————矩阵快速幂


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


Problem 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.

 


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.

 


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

 


Author


linle

 


Source


​​ 2007省赛集训队练习赛(6)_linle专场 ​​


 


Recommend


lcy   |   We have carefully selected several similar problems for you:   ​​1575​​​  ​​​1588​​​  ​​​3117​​​  ​​​2276​​​  ​​​2256​​ 

 


​​Statistic​​ | 

​​Submit​​ | 

​​Discuss​​ |

​​Note​​



矩阵快速幂解决
第一步,构造矩阵:

然后利用矩阵快速幂求得:

代码:

#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;
}


举报

相关推荐

0 条评论