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
题目大意:给出递推式子,要求输出第k项对m取模的值。
思路:观察f(x)的式子与数据范围,大数是不可能的,限时1000ms,那么解决此类问题就只有找规律与快速幂,考虑快速幂。
对比一下矩阵乘法快速幂与该题,完全吻合。只需要把单位矩阵小小的改变一下即可。
代码如下:
#include<set>
#include<map>
#include<list>
#include<deque>
#include<cmath>
#include<queue>
#include<string>
#include<vector>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ext/rope>
#include<iostream>
#include<algorithm>
#define pi acos(-1.0)
#define INF 0x3f3f3f3f
#define per(i,a,b) for(int i=a;i<=b;++i)
#define max(a,b) a>b?a:b
#define min(a,b) a<b?a:b
#define LL long long
//#define swap(a,b) {int t=a;a=b;b=t}
using namespace std;
using namespace __gnu_cxx;
struct node{
int a[15][15];
}p1,p2;//这样比较好用p2为单位矩阵,p1为构造的矩阵
void int1()//初始化
{
per(i,0,9)
{
per(j,0,9)
{
if(i==j) p2.a[i][j]=1;//
p1.a[i][j]=0;//
}
}
}
int mod;
node sum(node a,node b)
{
node c;
per(i,0,9)
{
per(j,0,9)
{
c.a[i][j]=0;
per(k,0,9)
{
c.a[i][j]+=(a.a[i][k]*b.a[k][j]%mod)%mod;//矩阵乘法
}
c.a[i][j]%=mod;
}
}
return c;
}
node pow(node x,node y,int a)//反复平方法求矩阵
{
while(a)//快速幂
{
if(a%2)
{
y=sum(y,x);//记录临时状态无法被整合的矩阵,并且最后作为乘积的最终答案
}
a/=2;
x=sum(x,x);//直接矩阵平方
}
return y;
}
int main()
{
int n,m,i,j;
while(~scanf("%d%d",&n,&m))
{
mod=m;
int1();
per(i,0,9) scanf("%d",&p1.a[0][i]);
per(i,1,9) p1.a[i][i-1]=1;//
if(n<10) printf("%d\n",n%mod);
else {
node p3=pow(p1,p2,n-9);
int s=0;
per(i,0,9) s+=p3.a[0][i]*(9-i)%mod;
printf("%d\n",s%mod);
}
}
return 0;
}