#if __INCLUDE_LEVEL__ == 0 #include __BASE_FILE__ constexpr array TEN{1, 10, 100, 1000, 10000, 100000}; constexpr int P = 115 << 20 | 1; using Mint = atcoder::static_modint

; const auto zs = [] { Mint z = Mint(atcoder::internal::primitive_root

).pow((P - 1) / 10); array zs; zs[0] = 1; for (int i : Rep(1, 10)) { zs[i] = z * zs[i - 1]; } return zs; }(); pair, vector> Go(int N, int K, const vector>& R, const vector& A) { Mint K_inv = Mint(K).inv(); vector f(TEN[N]); for (int k : Rep(0, K)) { int index = 0; for (int i : Rep(0, N)) { index += (R[k][i] + A[i]) % 10 * TEN[i]; } f[index] = K_inv; } for (int i : Rep(0, N)) { vector nf(TEN[N]); for (int o = 0; o < TEN[N]; o += TEN[i + 1]) { for (int s : Rep(0, 10)) { for (int t : Rep(0, 10)) { Mint z = zs[s * t % 10]; for (int j : Rep(0, TEN[i])) { nf[o + s * TEN[i] + j] += f[o + t * TEN[i] + j] * z; } } } } f = move(nf); } vector, vector>> seg(2 * TEN[N]); Mint inv = Mint(TEN[N]).inv(); for (int index : Rep(0, TEN[N])) { int e = 0; for (int i : Rep(0, N)) { e += index / TEN[i] * A[i]; } seg[TEN[N] + index] = {{inv}, {zs[e % 10], -f[index]}}; } for (int i : Rev(Rep(1, TEN[N]))) { const auto& [a, b] = seg[2 * i]; const auto& [c, d] = seg[2 * i + 1]; ranges::transform(atcoder::convolution(a, d), atcoder::convolution(b, c), back_inserter(seg[i].first), plus{}); seg[i].second = atcoder::convolution(b, d); } return seg[1]; } Mint Bm(vector a, vector b, int64_t n) { while (n > 0) { auto nb = b; for (int i = 1; i < Sz(nb); i += 2) { nb[i] = -nb[i]; } auto na = atcoder::convolution(a, nb); nb = atcoder::convolution(b, nb); a.clear(); for (int i = n & 1; i < Sz(na); i += 2) { a.push_back(na[i]); } for (int i : Rep(0, Sz(b))) { b[i] = nb[2 * i]; } n >>= 1; } return a[0] / b[0]; } void Solve() { int N, K; int64_t T; IN(N, K, T); vector A(N); IN(A); vector R(K, vector(N)); IN(R); auto [numer, denom] = Go(N, K, R, A); auto [numer2, denom2] = Go(N, K, R, vector(N)); numer = atcoder::convolution(numer, denom2); denom = atcoder::convolution(denom, numer2); denom = atcoder::convolution(denom, {1, -1}); Mint ans = Bm(numer, denom, T); OUT(ans); } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); Solve(); } #elif __INCLUDE_LEVEL__ == 1 #include #include template concept MyRange = std::ranges::range && !std::convertible_to; template concept MyTuple = std::__is_tuple_like::value && !MyRange; namespace std { istream& operator>>(istream& is, MyRange auto&& r) { for (auto&& e : r) is >> e; return is; } istream& operator>>(istream& is, MyTuple auto&& t) { apply([&](auto&... xs) { (is >> ... >> xs); }, t); return is; } ostream& operator<<(ostream& os, MyRange auto&& r) { auto sep = ""; for (auto&& e : r) os << exchange(sep, " ") << e; return os; } ostream& operator<<(ostream& os, MyTuple auto&& t) { auto sep = ""; apply([&](auto&... xs) { ((os << exchange(sep, " ") << xs), ...); }, t); return os; } template * = nullptr> istream& operator>>(istream& is, T& x) { int v; is >> v; x = T::raw(v); return is; } template * = nullptr> ostream& operator<<(ostream& os, const T& x) { return os << x.val(); } } // namespace std using namespace std; #define Rev views::reverse #define Rep(...) [](int l, int r) { return views::iota(min(l, r), r); }(__VA_ARGS__) #define Sz(r) int(size(r)) #define IN(...) (cin >> forward_as_tuple(__VA_ARGS__)) #define OUT(...) (cout << forward_as_tuple(__VA_ARGS__) << '\n') #endif // __INCLUDE_LEVEL__ == 1