Description
In our daily life we often use 233 to express our feelings. actually, we may say 2333,233 33, or 233333... in the same meaning. and here is the question: Suppose we have a matrix called 233 matrix. in the first line, it wocould be 233,233 3, 23333... (It means a 233 = 2333, A 23333 =, A = ...) besides, in 233 matrix, we got a I, j = A I-1, J + a I, J-1 (I, j = 0 ). now you have known a, 0, A, 0, ..., A n, 0, cocould You Tell Me A n, m in the 233 matrix?
Input
There are multiple test cases. Please process till EOF.
For each case, the first line contains two postive integers n, m (n ≤ 10, m ≤ 10 9 ). the second line contains N integers, A 1,0, A 2,0 ,..., a n, 0 (0 ≤ a I, 0 <2 31 ).
Output
For each case, output a n, m mod 10000007.
Sample Input
1 112 20 03 723 47 16
Sample output
234279972937
Hint
Due to the large scope of M data, this topic cannot be directly used for brute force computing. Matrix Multiplication is used here. Matrix Multiplication can obtain the next column from each column. Then, the multiplication of the matrix accelerates the computation using the fast power.
The square matrix of N + 2 rows is constructed because 2333 can be multiplied by 10 and 3.
It is roughly as follows:
10 0 0 0 ...... 0 1
10 1 0 0 ...... 0 1
10 1 1 0 ...... 0 1
......
10 1 1 1 ...... 1 1
0 0 0 ...... 0 1
The required column matrix is roughly as follows:
23 ...... 3
A, 0
A 2, 0
......
A n, 0
3
The correctness of recursion can be calculated and verified.
Here, the matrix is completed through struct and operator overloading.
Code:
#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <algorithm>#include <set>#include <map>#include <vector>#include <queue>#include <string>#define inf 0x3fffffff#define esp 1e-10#define N 10000007#define LL long longusing namespace std;struct Mat{ LL val[15][15]; int len; Mat operator = (const Mat& a) { for (int i = 0; i < len; ++i) for (int j = 0; j < len; ++j) val[i][j] = a.val[i][j]; len = a.len; return *this; } Mat operator * (const Mat& a) { Mat x; memset(x.val, 0, sizeof(x.val)); x.len = len; for (int i = 0; i < len; ++i) for (int j = 0; j < len; ++j) for (int k = 0; k < len; ++k) if (val[i][k] && a.val[k][j]) x.val[i][j] = (x.val[i][j] + (val[i][k]*a.val[k][j])%N)%N; return x; } Mat operator ^ (const int& a) { int n = a; Mat x, p = *this; memset(x.val, 0, sizeof(x.val)); x.len = len; for (int i = 0; i < len; ++i) x.val[i][i] = 1; while (n) { if (n & 1) x = x * p; p = p * p; n >>= 1; } return x; }};int n, m;LL a[15], ans;void Make(Mat &p){ p.len = n + 2; memset(p.val, 0, sizeof(p.val)); for (int i = 0; i <= n; ++i) p.val[i][0] = 10; for (int i = 0; i <= n+1; ++i) p.val[i][n+1] = 1; for (int i = 1; i <= n; ++i) for (int j = 1; j <= i; ++j) p.val[i][j] = 1;}int main(){ //freopen("test.txt", "r", stdin); while (scanf("%d%d", &n, &m) != EOF) { Mat p; Make(p); p = p ^ m; a[0] = 23; a[n+1] = 3; for (int i = 1; i <= n; ++i) scanf("%I64d", &a[i]); ans = 0; for (int i = 0; i <= n+1; ++i) ans = (ans + (p.val[n][i]*a[i])%N)%N; printf("%I64d\n", ans); } return 0;}
ACM learning process-hdu5015 233 matrix (matrix Rapid power) (2014 Shaanxi online competition)