题目链接:点我
题意:
如题给出的公式,让你求 f(n) mod m的值;
思路:
矩阵快速幂;
根据题意构造矩阵为:
⎛⎝⎜⎜⎜⎜⎜⎜a110.....a201.......a300.......a400....0................1ad00...0⎞⎠⎟⎟⎟⎟⎟⎟
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long LL;
int n, mod,d;
struct mat{
LL a[20][20];
mat(){memset(a, 0,sizeof(a)); }
mat operator *(const mat q){
mat c;
for(int i = 1; i <= d; ++i)
for(int k = 1; k <= d;++k)
if(a[i][k])
for(int j = 1; j<= d; ++j){
c.a[i][j] += a[i][k] * q.a[k][j];
if(c.a[i][j] >= mod) c.a[i][j] %= mod;
}return c;
}
};
mat qpow(mat x, int n){
mat ans;
for(int i = 1; i <= 15; ++i)
ans.a[i][i] = 1;
while(n){
if(n&1) ans =ans * x;
x =x *x ;
n >>= 1;
}return ans;
}
int main(){
int f[20];
while(scanf("%d %d %d", &d, &n ,&mod) != EOF&&(d||mod||n)){
mat ans;
for(int i = 1; i <= d; ++i)
scanf("%d", &ans.a[1][i]);
for(int i = d; i > 0; --i)
scanf("%d", &f[i]);
if(n <= d){
printf("%d\n",f[n] % mod);
continue;
}for(int i = 2; i <= d; ++i)
ans.a[i][i-1] = 1;
ans = qpow(ans,n-d);
int sum = 0;
for(int i = 1; i <= d; ++i)
sum = (sum + f[i] * ans.a[1][i]) % mod;
printf("%d\n",sum);
}return 0;
}