uva 10870 递推关系矩阵快速幂模
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 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 <= 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 than m.
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
|
题目大意:f(n)=a1*f(n-1)+a2*f(n-2)+.....+ad*f(n-d)
#include<iostream> #include<cstring> #include<cstdio> using namespace std; #define Max 20 typedef long long LL; struct Matrix { LL a[Max][Max]; int n; }; Matrix Matrix_mult_mod(Matrix A,Matrix B,int m) { int i,j,k; Matrix C; C.n=A.n; memset(C.a,0,sizeof(C.a)); for(i=1;i<=A.n;i++) { for(j=1;j<=A.n;j++) { for(k=1;k<=A.n;k++) { C.a[i][j]=(C.a[i][j]+A.a[i][k]*B.a[k][j])%m; } } } return C; }
Matrix Matrix_pow_mod(Matrix A,int n,int m) { Matrix t; int i,j; t.n=A.n; memset(t.a,0,sizeof(t.a)); for(i=1;i<=A.n;i++) t.a[i][i]=1; for(i=1;i<=A.n;i++) for(j=1;j<=A.n;j++) A.a[i][j]%=m; while(n) { if(n&1) t=Matrix_mult_mod(t,A,m); n>>=1; A=Matrix_mult_mod(A,A,m); } return t; } void deal(int d,int n,int m) { int i,j; LL dd[Max],dd1[Max]; Matrix A; A.n=d; memset(A.a,0,sizeof(A.a)); for(i=1,j=2;j<=d;i++,j++) A.a[i][j]=1; for(j=d,i=1;i<=d;i++,j--) scanf("%ll",&A.a[d][j]); for(i=1;i<=d;i++) scanf("%ll",dd+i); A=Matrix_pow_mod(A,n-d,m); for(i=1;i<=d;i++) { dd1[i]=0; for(j=1;j<=d;j++) dd1[i]=(dd1[i]+A.a[i][j]*dd[j])%m; } printf("%ll\n",dd1[d]); }
int main() { int d,n,m; while(scanf("%d %d %d",&d,&n,&m),d+n+m) deal(d,n,m); return 0; }