Problem A
Recurrences
Input: standard input
Output: standard output
Consider recurrent functions of the following form:
f(n) = a1 f(n - 1) + a2 f(n - 2) + a3 f(n - 3) + ... + ad f(n - d), for n > d.
a1, a2, ..., ad - 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 dnon-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 <= 231 - 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 thanm.
Sample Input Output for 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 | 1 55 423
|
解题报告: 快速幂,构造好矩阵即可。注意当n<=d时,直接输出值就好,否则计算转移矩阵n-d次幂,乘上初始矩阵。
代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef int Matrix[16][16];
long long c[16][16];
int mod;
int n;
void mul(Matrix& a, Matrix& b)
{
memset(c, 0, sizeof(c));
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
for(int k=0; k<n; k++)
c[i][j]+=(long long)(a[i][k]*b[k][j]);
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
a[i][j]=c[i][j]%mod;
}
void powMatrix(Matrix& a, int b)
{
Matrix res;
memset(res, 0, sizeof(res));
for(int i=0; i<n; i++) res[i][i]=1;
while(b)
{
if(b&1)
mul(res, a);
mul(a, a);
b>>=1;
}
memcpy(a, res, sizeof(res));
}
int main()
{
int k;
while(scanf("%d%d%d", &n, &k, &mod) && (n||k||mod))
{
Matrix a;
memset(a, 0, sizeof(a));
for(int i=1; i<n; i++)
a[i-1][i]=1;
for(int i=0; i<n; i++)
scanf("%d", &a[i][0]), a[i][0]%=mod;
Matrix b;
memset(b, 0, sizeof(b));
for(int i=n-1; i>=0; i--)
scanf("%d", &b[0][i]), b[0][i]%=mod;
if(k>n)
{
powMatrix(a, k-n);
mul(b, a);
printf("%d\n", b[0][0]);
}
else
{
printf("%d\n", b[0][n-k]);
}
}
}