您的位置:首页 > 其它

HDU 1757 A Simple Math Problem(矩阵快速幂构造)

2016-07-15 13:55 447 查看
http://acm.hdu.edu.cn/showproblem.php?pid=1757

A Simple Math Problem

Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 4082 Accepted Submission(s): 2464

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

构造下矩阵剩下的就OK了。

【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)】=【f(9) f(8) f(7) f(6) f(5) f(4) f(3) f(2) f(1) f(0)】*



然后直接模板求就OK了。

下面是AC代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 12

int mod;
struct Mat
{
int a[12][12];
void init()
{
memset(a,0,sizeof(a));
for(int i=0; i<N; i++)
{
a[i][i]=1;
}
}
};

Mat mul(Mat a,Mat b) //(a*b)%mod  矩阵乘法
{
Mat ans;
for(int i=0; i<N; i++)
{
for(int j=0; j<N; j++)
{
ans.a[i][j]=0;
for(int k=0; k<N; k++)
{
ans.a[i][j]=(ans.a[i][j]%mod)+(a.a[i][k]%mod)*(b.a[k][j]%mod);
}
ans.a[i][j]%=mod;
}
}
return ans;
}

Mat power(Mat a,int num)//(a^n)%mod  矩阵快速幂
{
Mat ans;
ans.init();
while(num)
{
if(num&1)
{
ans=mul(ans,a);
}
num>>=1;
a=mul(a,a);
}
return ans;
}

int main()
{
int num;
while(~scanf("%d%d",&num,&mod))
{
int c[11];
for(int i=0; i<10; i++)
{
scanf("%d",&c[i]);
}
Mat a,b,ans;
memset(a.a,0,sizeof(a.a));
memset(b.a,0,sizeof(b.a));
for(int i=0; i<10; i++)
{
a.a[i][0]=c[i];
a.a[i][i+1]=1;
}
a=power(a,num-9);
for(int i=0; i<10; i++)
{
b.a[0][i]=9-i;
}
for(int i=0; i<1; i++)
{
for(int j=0; j<10; j++)
{
ans.a[i][j]=0;
for(int k=0; k<10; k++)
{
ans.a[i][j]=(ans.a[i][j]%mod)+(b.a[i][k]%mod)*(a.a[k][j]%mod);
}
ans.a[i][j]%=mod;
}
}
printf("%d\n",ans.a[0][0]%mod);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  HDU