#include #include #include // #include // https://github.com/amiast/cpp-utility #ifndef KOTONE_BERLEKAMP_MASSEY_HPP #define KOTONE_BERLEKAMP_MASSEY_HPP 1 #include #include // #include // https://github.com/amiast/cpp-utility #ifndef KOTONE_INTERNAL_TYPE_TRAITS_HPP #define KOTONE_INTERNAL_TYPE_TRAITS_HPP 1 #include namespace kotone { template concept number = std::is_arithmetic_v; template concept signed_number = std::signed_integral || std::floating_point; template concept compatible_modint = requires(mint a, mint b, int64_t x) { { mint::mod() } -> std::convertible_to; mint{}; mint{1}; mint{x}; { a + b } -> std::same_as; { a - b } -> std::same_as; { -a } -> std::same_as; { a * b } -> std::same_as; { a / b } -> std::same_as; { a.inv() } -> std::same_as; { a.pow(x) } -> std::same_as; { a += b } -> std::same_as; { a -= b } -> std::same_as; { a *= b } -> std::same_as; { a /= b } -> std::same_as; { a == b } -> std::convertible_to; { a != b } -> std::convertible_to; { a.val() } -> std::convertible_to; }; template concept additive = requires(T a, T b) { T{}; { a + b } -> std::same_as; { a - b } -> std::same_as; { -a } -> std::same_as; { a == b } -> std::convertible_to; { a != b } -> std::convertible_to; }; template concept mutable_additive = ( additive && requires(T a, T b) { { a += b } -> std::same_as; { a -= b } -> std::same_as; { ++a } -> std::same_as; { --a } -> std::same_as; { a++ } -> std::same_as; { a-- } -> std::same_as; } ); } // namespace kotone #endif // KOTONE_INTERNAL_TYPE_TRAITS namespace kotone { // Returns a vector containing the minimum number of coefficients of the recurrence relation // given the specified initial condition in `vec`. template std::vector berlekamp_massey(const std::vector &vec) { assert(vec.size() <= 100000000u); int len = static_cast(vec.size()); std::vector coeffs{1}, last_coeffs{1}; int curr_len = 0, num_steps = 1; mint last_diff = 1; for (int i = 0; i < len; i++) { mint diff = vec[i]; for (int j = 1; j <= curr_len; j++) diff += coeffs[j] * vec[i - j]; if (diff == 0) { num_steps++; continue; } std::vector temp = coeffs; mint factor = diff / last_diff; if (coeffs.size() < last_coeffs.size() + num_steps) { coeffs.resize(last_coeffs.size() + num_steps); } for (unsigned j{}; j < last_coeffs.size(); j++) { coeffs[j + num_steps] -= factor * last_coeffs[j]; } if (curr_len * 2 <= i) { last_coeffs = temp; curr_len = i + 1 - curr_len; last_diff = diff; num_steps = 1; } else { num_steps++; } } coeffs.erase(coeffs.begin()); for (mint &c : coeffs) c = -c; return coeffs; } } // namespace kotone #endif // KOTONE_BERLEKAMP_MASSEY_HPP using mint = atcoder::modint1000000007; std::vector> prod(const std::vector> &a, const std::vector> &b) { int n = a.size(), m = b.size(), l = b[0].size(); std::vector result(n, std::vector(l)); for (int i = 0; i < n; i++) { for (int k = 0; k < m; k++) { for (int j = 0; j < l; j++) { result[i][j] += a[i][k] * b[k][j]; } } } return result; } std::vector> pow(const std::vector> &a, int64_t k) { if (k <= 1) return a; std::vector> result = pow(a, k / 2); result = prod(result, result); if (k % 2 == 1) result = prod(result, a); return result; } int main() { int a, b, c, d, e; int64_t N; std::cin >> a >> b >> c >> d >> e >> N; std::vector init{a, b}; for (int i = 2; i < 10; i++) init.push_back(init[i - 1] * c + init[i - 2] * d + e); for (int i = 0; i < 9; i++) init[i + 1] += init[i]; if (N < 10) { std::cout << init[N].val() << std::endl; return 0; } std::vector rec = kotone::berlekamp_massey(init); int K = rec.size(); std::vector mat(K, std::vector(K)); mat[0] = rec; for (int i = 1; i < K; i++) mat[i][i - 1] = 1; mint result = 0; auto exp = pow(mat, N - (K - 1)); for (int i = 0; i < K; i++) result += exp[0][i] * init[K - 1 - i]; std::cout << result.val() << std::endl; }