题目链接:点我
题目
题意:
如题给出的公式,让你求 f(n) mod m的值;
思路:
矩阵快速幂;
根据题意构造矩阵为:
⎝⎜⎜⎜⎜⎛a110.....a201.......a300.......a400....0................1ad00...0⎠⎟⎟⎟⎟⎞
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| #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; }
|