- 233 Matrix
中文English
Given a matric A. The first row of matrix A is 0, 233, 2333, 23333…(i.e., A(0,0)=0,A(0,1)=233,A(0,2)=2333,A(0,3)=23333…). Besides, A(i,j)=A(i-1,j)+A(i,j-1).
Given an array X with n integers. X[i] is A(i+1,0), (i.e., X[0] is A(1,0), X[1] is A(2,0) …), and a positive integer m.
Return the value of A(n,m) % 10000007.
Example
Example1
Input: X=[1], m=1
Output: 234
Explanation:
[[0,233],
[1,234]]
Example2
Input: X=[0,0], m=2
Output: 2799
Explanation:
[[0,233,2333],
[0,233,2566],
[0,233,2799]]
Notice
n <=1 0, m <= 10^9
0 =< A(i,0) < 2^31
Solution 1: Matrix quick power
this question means that demand
[0, 233, 2333, 23333, ...]
[X_0,,,, ...???]
[X_1,,,, ...???]
...
[X_ (the n- -1),?,?,?, ...]
matrix a (n + 1 line, n + 1 column) inside the section a (n, m) value of the item, where a (i, j) = a (i- . 1, J) + a (I, J-. 1).
Example Output. 1 is:
[0 233]
[. 1 234]
Example Output 2 is
[02332333]
[02332366]
[02332799]
this Road I find it hard to question. The following links explain very well:
https://www.cnblogs.com/whatbeg/p/3971994.html
analyse as below.
because
A(n,m)=A(n-1,m)+A(n,m-1)
=A(n-2,m)+A(n-1,m-1)+A(n,m-1)
=A(n-3,m)+A(n-2,m-1)+A(n-1,m-1)+A(n,m-1)
=...
=A(0,m)+A(1,m-1)+A(2,m-1)+...+A(n,m-1)
That is, as shown below (for the original source https://www.cnblogs.com/whatbeg/p/3971994.html):
red box i.e., A [n] [m], and a value of the green box.
we know
A(n,m) =A(0,m)+A(1,m-1)+A(2,m-1)+...+A(n,m-1)
Note that 233 = 23 * 10 + 3, 2333 = 233 * 10 + 3, 23333 * 10 = 2333 + 3
we have
A(0, 0) = 0
A(0, 1) = 23
A(0,m) = A(0,m-1) * 10 + 3, m>=2
and so
A(n,m) = A(0,m-1) * 10 + A(1,m-1) + A(2,m-1) + ... + A(n,m-1) + 3, m >= 2
Therefore, for m> = 2, we find equivalent to the following matrix operation.
We call on the big map matrix M, then pay attention if the X dimension is n, the dimension of M is the (n + 2) * (n +2). When m> = 2,
(a0,m a1,m, a2,m, ..., an,m 3) = M * (a0,m-1 a1,m-1 a2,m-1 ... an,m-1 3)
= M^2 * (a0,m-2 a1,m-2 a2,m-2 ... an,m-2 3)
...
= M^m-1 * (a0,1 a1,1 a2,1 ... an,1 3)
Note, however, above all for m> = 2, so we must first find m = 0 and m = 1 case.
And when m = 0,
(a0,0 a2,0 ... AN A1,0, 0. 3) = (the X1 ... Xn-X0 0. 3. 1) and final results of // 0.
when m =. 1,
(a0,1 a1,1 a2,1 ... AN,. 1. 3) = (233, 233 + X0, X0 + 233 + the X1, ..., 233 + + ... + X0 + the X1-Xn. 1,. 3) // and final results of the first column
further analysis,
(a0,1 a1,1 a2,1 ... an,1 3) =
(233, 233+X0, 233+X0+X1, ..., 233+X0+X1+...+Xn-1, 3) =
(233, 233, 233, ..., 233, 3) + (0, X0, X0+X1, ..., X0+X1+...+Xn-1, 0) =
(233, 233, 233, ..., 233, 3) + M * (0, X0, X1, ..., Xn-1, 0) =
(23, 233, 233, ..., 233, 3) + M * (a0,0 a1,0 a2,0 ... an,0 0)
and
(233, 233, 233, ..., 233, 3) = M * (23, 0, ..., 0, 3)
and so,
(a0,1 a1,1 a2,1 ... an,1 3) = M * [(23, 0, ..., 0, 3) + (a0,0 a1,0 a2,0 ... an,0 0)]
(a0,m a1,m, a2,m, ..., an,m 3) = M^m-1 * (a0,1 a1,1 a2,1 ... an,1 3)
= M^m* (23, 0, ..., 0, 3) + M^m * (a0,0 a1,0 ... an,0 3)
We named the M ^ m Mm, because only then we claim a (n, m), so that
a (n, m) = Mm (n, 0) * 23 + Mm (n + 1, m) * 3 + Mm * (a0,0 a1,0 ... an , 0 3)
code show as below:
class Matrix {
public:
vector<vector<long long>> matrix;
Matrix(int n, int mod) {
dim = n;
this->mod = mod;
matrix.resize(dim, vector<long long>(dim, 0LL));
}
void unit() {
for (int i = 0; i < dim; ++i) {
for (int j = 0; j < dim; ++j) {
//matrix[i][j] = (long long)(i == j);
if (i == j) matrix[i][j] = 1LL;
}
}
}
Matrix operator * (const Matrix & m) const {
Matrix result(dim, mod);
for (int i = 0; i < dim; ++i) {
for (int k = 0; k < dim; ++k) {
if (matrix[i][k] == 0) continue;
for (int j = 0; j < dim; ++j) {
result.matrix[i][j] += matrix[i][k] * m.matrix[k][j];
result.matrix[i][j] %= mod;
}
}
}
return result;
}
Matrix power(int n) {
Matrix result(dim, mod);
result.unit();
while(n) {
if (n & 0x1) result = result * (*this);
//matrix = matrix * matrix;
*this = (*this) * (*this);
n /= 2;
}
return result;
}
private:
int dim, mod;
};
class Solution {
public:
/**
* @param X: a list of integers
* @param m: an integer
* @return: return an integer
*/
int calcTheValueOfAnm(vector<int> &X, int m) {
int n = X.size();
if ((n == 0) && (m == 0)) return 0;
if (m == 0) return X[n - 1];
Matrix mx(n + 2, 10000007);
for(int i = 0; i <= n; ++i) mx.matrix[i][0] = 10;
for(int i = 0; i <= n + 1; ++i) mx.matrix[i][n + 1] = 1;
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= i; ++j)
mx.matrix[i][j] = 1;
Matrix tmp = mx.power(m);
long long answer = 23 * tmp.matrix[n][0] + 3 * tmp.matrix[n][n + 1];
for (int i = 1; i <= n; ++i) {
answer += tmp.matrix[n][i] * X[i - 1];
}
answer %= 10000007;
return answer;
}
};
Method 2:
the DP. This problem may also feel a DP do, but the time complexity may be too large?