A Simple Math Problem
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5025 Accepted Submission(s): 3037
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.
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cstring>
using namespace std;
#define maxn 10
#define me(x) memset(x,0,sizeof(x))
#define ll long long
int mod;
struct mat//用結構體封裝矩陣
{
ll m[maxn][maxn];
}unit,temp,F;
///這三個矩陣分別爲,單位矩陣、ai矩陣、F矩陣
void init()//初始化
{
me(unit.m);
me(temp.m);
me(F.m);
for(int i=0;i<10;i++)//單行
{
F.m[i][0]=9-i;
unit.m[i][i]=1;
}
for(int i=0;i<9;i++)///只需要把第i+1行第i列修改就行
{
temp.m[i+1][i]=1;
}
}
void print(mat a)//自己寫的打印函數
{
int i,j;
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
printf("%d ",a.m[i][j]);
puts("");
}
puts("");
return ;
}
mat operator*(mat a,mat b)//對*運算符重載爲矩陣相乘
{
mat p;
for(int i=0;i<10;i++)
{
for(int j=0;j<10;j++)
{
p.m[i][j]=0;
for(int w=0;w<10;w++)
{
p.m[i][j]+=a.m[i][w]*b.m[w][j]%mod;
p.m[i][j]%=mod;
}
}
}
return p;
}
ll pow(int k)//矩陣快速冪
{
mat ans;
ans=unit;
//print(ans);
//print(ans);
//cout<<k<<endl;
//int count=0;
while(k)
{
//count++;
if(k&1)
{
ans=ans*temp;
}
temp=temp*temp;
k=k>>1;
}
//cout<<count<<endl;
ans=ans*F; //print(ans);
return ans.m[0][0]%mod;//因爲ans[0][0]就是f(n);
}
int main()
{
int k;
while(scanf("%d %d",&k,&mod)!=EOF)
{
init();
for(int i=0;i<10;i++)
{
scanf("%d",&temp.m[0][i]);
}
//cout<<endl<<endl;
//print(temp);
if(k<10) {printf("%d\n",k%mod);continue;}
ll ans;
//print(temp);
// print(F);
ans=pow(k-9);
// ans=unit*F;
cout<<ans%mod<<endl;
}
return 0;
}