Problem:
Score : 100 points

Problem Statement

There is a simple directed graph G with N vertices, numbered 1, 2, \ldots, N.

For each i and j (1 \leq i, j \leq N), you are given an integer a_{i, j} that represents whether there is a directed edge from Vertex i to j.
If a_{i, j} = 1, there is a directed edge from Vertex i to j; if a_{i, j} = 0, there is not.

Find the number of different directed paths of length K in G, modulo 10^9 + 7.
We will also count a path that traverses the same edge multiple times.

Constraints

All values in input are integers.

1 \leq N \leq 50

1 \leq K \leq 10^{18}

a_{i, j} is 0 or 1.

a_{i, i} = 0

Input

Input is given from Standard Input in the following format:

N K
a_{1, 1} \ldots a_{1, N}
:
a_{N, 1} \ldots a_{N, N}

Output

Print the number of different directed paths of length K in G, modulo 10^9 + 7.

Sample Input 1

4 2
0 1 0 0
0 0 1 1
0 0 0 1
1 0 0 0

Sample Output 1

6

G is drawn in the figure below:

There are six directed paths of length 2:

1 → 2 → 3

1 → 2 → 4

2 → 3 → 4

2 → 4 → 1

3 → 4 → 1

4 → 1 → 2

Sample Input 2

3 3
0 1 0
1 0 1
0 0 0

Sample Output 2

3

G is drawn in the figure below:

There are three directed paths of length 3:

1 → 2 → 1 → 2

2 → 1 → 2 → 1

2 → 1 → 2 → 3

Sample Input 3

6 2
0 0 0 0 0 0
0 0 1 0 0 0
0 0 0 0 0 0
0 0 0 0 1 0
0 0 0 0 0 1
0 0 0 0 0 0

Sample Output 3

1

G is drawn in the figure below:

There is one directed path of length 2:

4 → 5 → 6

Sample Input 4

1 1
0

Sample Output 4

0

Sample Input 5

10 1000000000000000000
0 0 1 1 0 0 0 1 1 0
0 0 0 0 0 1 1 1 0 0
0 1 0 0 0 1 0 1 0 1
1 1 1 0 1 1 0 1 1 0
0 1 1 1 0 1 0 1 1 1
0 0 0 1 0 0 1 0 1 0
0 0 0 1 1 0 0 1 0 1
1 0 0 0 1 0 1 0 0 0
0 0 0 0 0 1 0 0 0 0
1 0 1 1 1 0 1 1 1 0

Sample Output 5

957538352

Be sure to print the count modulo 10^9 + 7.

Solution in C++14 (Clang 3.8.0) (judge verdict: Accepted)

#include <iostream>
#include <vector>
#include <cassert>

using namespace std;
typedef long long ll;

struct mint{
    static const long long MOD = 1000000007;

    long long v;

    mint() : v(0) {}
    mint(long long x){
        x = x % MOD;
        if(x < 0){ x += MOD; }
        v = x;
    }
    mint& operator+=(mint a){
        v += a.v;
        if(v >= MOD){ v -= MOD; }
        return *this;
    }
    mint& operator*=(mint a){
        v *= a.v;
        v %= MOD;
        return *this;
    }
    mint& operator-=(mint a){
        v -= a.v;
        if(v < 0){ v += MOD; }
        return *this;
    }
    mint& operator/=(mint a){
        return (*this) *= a.inv();
    }

    mint operator*(mint a) const{
        return mint(v) *= a;
    }

    mint operator+(mint a) const {
        return mint(v) += a;
    }

    mint operator-(mint a) const {
        return mint(v) -= a;
    }

    mint operator/(mint a) const {
        return mint(v) /= a;
    }

    mint pow(long long k) const {
        mint res(1),tmp(v);
        while(k){
            if(k&1) res *= tmp;
            tmp *= tmp;
            k >>= 1;
        }
        return res;
    }
    mint inv(){return pow(MOD - 2); }

    static mint comb(long long n, int k){
        mint res(1);
        for(int i = 0; i < k; ++i){
            res *= mint(n - i);
            res /= mint(i + 1);
        }
        return res;
    }

    static mint factorial(long long n){
        mint res(1);
        for(int i = n; i > 1; --i){
            res *= mint(i);
        }
        return res;
    }

    bool operator<(const mint &a) const {
        return v < a.v;
    };
};

mint operator*(long long l, mint r){ return r * l; }


template<class T>
struct Matrix {
    int nrow, ncol;
    vector<T> v;

    static Matrix<T> identity(int n){
        Matrix<T> ret(n, n);
        for(int i = 0; i < n; ++i){ ret.at(i, i) = 1; }
        return ret;
    }

    Matrix(int nrow, int ncol) : nrow(nrow), ncol(ncol), v(nrow * ncol, 0) {};
    Matrix(const Matrix<T>& m) : nrow(m.nrow), ncol(m.ncol), v(m.v) {};
    T& at(int i, int j){ return v.at(i * ncol + j); }
    const T& at(int i, int j) const { return v.at(i * ncol + j); }

    Matrix<T> operator*(const Matrix<T>& other){
        assert(ncol == other.nrow);
        Matrix<T> ret(nrow, other.ncol);
        for(int i = 0; i < nrow; ++i){
            for(int j = 0; j < other.ncol; ++j){
                for(int k = 0; k < ncol; ++k){
                    ret.at(i, j) += this->at(i, k) * other.at(k, j);
                }
            }
        }
        return ret;
    }

    vector<T> operator*(const vector<T>& v){
        assert(ncol == v.size());
        vector<T> ret(nrow, 0);
        for(int i = 0; i < nrow; ++i){
            for(int j = 0; j < ncol; ++j){
                ret.at(i) += this->at(i, j) * v.at(j);
            }
        }
        return ret;
    }

    Matrix<T> pow(long long k){
        assert(nrow == ncol);
        Matrix<T> ret(Matrix<T>::identity(nrow));
        Matrix<T> tmp(*this);
        while(k){
            if(k & 1) ret = ret * tmp;
            tmp = tmp * tmp;
            k >>= 1;
        }
        return ret;
    }
};

template<class T>
vector<T> operator*(const vector<T>& v, const Matrix<T>& m){
    assert(v.size() == m.nrow);
    vector<T> ret(m.ncol, 0);
    for(int i = 0; i < ret.size(); ++i){
        for(int j = 0; j < v.size(); ++j){
            ret.at(i) += v.at(j) * m.at(j, i);
        }
    }
    return ret;
}


int main(){
    ll n, k;
    cin >> n >> k;
    Matrix<mint> m(n, n);
    for(int i = 0; i < n; ++i){
        for(int j = 0; j < n; ++j){
            ll aij;
            cin >> aij;
            if(aij){
                m.at(i, j) = 1;
            }
        }
    }

    vector<Matrix<mint>> pow;
    pow.push_back(m);
    for(ll k2 = k; k2 > 0; k2 /= 2){
        pow.push_back(pow.back() * pow.back());
    }

    Matrix<mint> mk = Matrix<mint>::identity(n);
    for(ll i = 0; i < pow.size(); ++i){
        if((k >> i) & 1){
            mk = mk * pow.at(i);
        }
    }

    mint ans = 0;
    for(int i = 0; i < n; ++i){
        for(int j = 0; j < n; ++j){
            ans += mk.at(i, j);
        }
    }
    cout << ans.v << endl;

    return 0;
}