LintCode 946: 233 Matrix (Matrix fast power Classic title)

  1. 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):
Here Insert Picture Description
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.
Here Insert Picture Description
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?

Published 577 original articles · won praise 21 · views 80000 +

Guess you like

Origin blog.csdn.net/roufoo/article/details/100844580