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.
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.
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]); } } }