传送门
Consider recurrent functions of the following form:
f(n) = a1f(n − 1) + a2f(n − 2) + a3f(n − 3) + … + adf(n − d), for n > d,
where a1, a2, … , ad are arbitrary constants.
A famous example is the Fibonacci sequence, defined as: f(1) = 1, f(2) = 1, f(n) = f(n − 1) +
f(n − 2). Here d = 2, a1 = 1, a2 = 1.
Every such function is completely described by specifying d (which is called the order of recurrence),
values of d coefficients: a1, a2, … , ad, and values of f(1), f(2), … , f(d). You’ll be given these numbers,
and two integers n and m. Your program’s job is to compute f(n) modulo m.
Input
Input file contains several test cases. Each test case begins with three integers: d, n, m, followed by
two sets of d non-negative integers. The first set contains coefficients: a1, a2, … , ad. The second set
gives values of f(1), f(2), … , f(d).
You can assume that: 1 ≤ d ≤ 15, 1 ≤ n ≤ 2
31 − 1, 1 ≤ m ≤ 46340. All numbers in the input will
fit in signed 32-bit integer.
Input is terminated by line containing three zeroes instead of d, n, m. Two consecutive test cases
are separated by a blank line.
Output
For each test case, print the value of f(n)( mod m) on a separate line. It must be a non-negative integer,
less than m.
Sample Input
1 1 100
2
1
2 10 100
1 1
1 1
3 2147483647 12345
12345678 0 12345
1 2 3
0 0 0
Sample Output
1
55
423
题目大意:
给定一个递推关系式
解题思路:
我们可以拿斐波那契数列来举例构造一个矩阵,
其实 根据上边这个斐波那契,我们可以做这道题了。首先还是要构造一个矩阵
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long LL;
LL d, n, MOD;
const int MAXN = 20;
LL a[MAXN], f[MAXN];
typedef struct
{
LL mat[MAXN][MAXN];
}Matrix;
Matrix Init()
{
Matrix I;
for(int i=0; i<d; i++)
{
for(int j=0; j<d; j++)
{
if(i == j)
I.mat[i][j] = 1;
else
I.mat[i][j] = 0;
}
}
return I;
}
Matrix Mul_Matrix(Matrix a, Matrix b)
{
Matrix c;
for(int i=0; i<d; i++)
{
for(int j=0; j<d; j++)
{
c.mat[i][j] = 0;
for(int k=0; k<d; k++)
{
c.mat[i][j] += a.mat[i][k]*b.mat[k][j];
c.mat[i][j] %= MOD;
}
}
}
return c;
}
Matrix quick_MOD_Matrix(LL m, Matrix a)
{
Matrix I = Init();
Matrix ans = I;
while(m)
{
if(m&1)
ans = Mul_Matrix(ans, a);
m>>=1;
a = Mul_Matrix(a, a);
}
return ans;
}
int main()
{
while(cin>>d>>n>>MOD)
{
if(d==0 && n==0 && MOD==0)
break;
Matrix P;
for(int i=0; i<d; i++)
cin>>P.mat[i][0];
for(int i=d-1; i>=0; i--)///方便
cin>>f[i];
if(n < d)
{
cout<<f[n]<<endl;
continue;
}
for(int i=0; i<d; i++)
{
for(int j=1; j<d; j++)
{
if(i==j-1)
P.mat[i][j] = 1;
else
P.mat[i][j] = 0;
}
}
Matrix tmp = quick_MOD_Matrix(n-d,P);
LL ans = 0;
for(int i=0; i<d; i++)
{
ans += tmp.mat[i][0]*f[i];
ans %= MOD;
}
ans = (ans%MOD+MOD)%MOD;
cout<<ans<<endl;
}
return 0;
}