#line 1 "3228.test.cpp" #define PROBLEM "https://yukicoder.me/problems/no/3228" #line 2 "ds/matrix.hpp" #include #include #include template struct Matrix { int H, W; std::vector> table; Matrix(int h, int w) : H(h), W(w), table(h, std::vector(w)) {} Matrix(const std::vector> &v) : H((int)v.size()), W((int)v[0].size()), table(v) {} std::vector &operator[](int i) { return table[i]; } const std::vector &operator[](int i) const { return table[i]; } static Matrix identity(int N) { Matrix res(N, N); for (int i = 0; i < N; i++) { res[i][i] = 1; } return res; } Matrix &operator+=(const Matrix &rhs) { assert(H == rhs.H && W == rhs.W && "DIMENSION must be the same"); for (int i = 0; i < H; i++) { for (int j = 0; j < W; j++) { table[i][j] += rhs[i][j]; } } return *this; } Matrix &operator-=(const Matrix &rhs) { assert(H == rhs.H && W == rhs.W && "DIMENSION must be the same"); for (int i = 0; i < H; i++) { for (int j = 0; j < W; j++) { table[i][j] -= rhs[i][j]; } } return *this; } Matrix operator*(const Matrix &rhs) const { assert(W == rhs.H && "MULTIPLICATION DIMENSION does not match"); Matrix res(H, rhs.W); for (int i = 0; i < H; i++) { for (int j = 0; j < W; j++) { if (table[i][j] == 0) continue; for (int k = 0; k < rhs.W; k++) { res[i][k] += table[i][j] * rhs[j][k]; } } } return res; } Matrix &operator*=(const Matrix &rhs) { return *this = *this * rhs; } Matrix pow(int64_t n) const { assert(H == W && "DIMENSION must be square"); Matrix res = identity(H); Matrix a = *this; while (n > 0) { if (n & 1) res *= a; a *= a; n >>= 1; } return res; } }; #line 3 "mod/modint.hpp" #include #include template struct ModInt { static_assert(MOD > 1, "MOD must be > 1"); uint32_t val; constexpr ModInt() : val(0) {} constexpr ModInt(const int64_t &x) : val(x >= 0 ? x % MOD : (MOD - (-x) % MOD) % MOD) {} constexpr uint32_t value() const { return val; } constexpr ModInt &operator+=(const ModInt &rhs) { val += rhs.val; if (val >= MOD) val -= MOD; return *this; } constexpr ModInt &operator-=(const ModInt &rhs) { if (val < rhs.val) val += MOD; val -= rhs.val; return *this; } constexpr ModInt &operator*=(const ModInt &rhs) { val = (uint64_t)val * rhs.val % MOD; return *this; } constexpr ModInt &operator/=(const ModInt &rhs) { return *this *= rhs.inverse(); } constexpr ModInt operator+() const { return *this; } constexpr ModInt operator-() const { return ModInt(val == 0 ? 0 : MOD - val); } friend constexpr ModInt operator+(ModInt lhs, const ModInt &rhs) { return lhs += rhs; } friend constexpr ModInt operator-(ModInt lhs, const ModInt &rhs) { return lhs -= rhs; } friend constexpr ModInt operator*(ModInt lhs, const ModInt &rhs) { return lhs *= rhs; } friend constexpr ModInt operator/(ModInt lhs, const ModInt &rhs) { return lhs /= rhs; } friend constexpr bool operator==(const ModInt &lhs, const ModInt &rhs) { return lhs.val == rhs.val; } friend constexpr bool operator!=(const ModInt &lhs, const ModInt &rhs) { return lhs.val != rhs.val; } constexpr ModInt pow(uint64_t n) const { ModInt res = 1, a = *this; while (n > 0) { if (n & 1) res *= a; a *= a; n >>= 1; } return res; } constexpr ModInt inverse() const { int64_t a = val, b = MOD, u = 1, v = 0; while (b) { int64_t t = a / b; a -= t * b; std::swap(a, b); u -= t * v; std::swap(u, v); } return ModInt(u); } friend std::ostream &operator<<(std::ostream &os, const ModInt &x) { return os << x.val; } friend std::istream &operator>>(std::istream &is, ModInt &x) { int64_t v; is >> v; x = ModInt(v); return is; } }; #line 4 "3228.test.cpp" #include using namespace std; void solve() { int64_t a, b, c, d, e, N; cin >> a >> b >> c >> d >> e >> N; using Mint = ModInt<1000000007>; if (N < 2) { Mint out = (N ? a + b : a); cout << out << '\n'; return; } Matrix transition(4, 4), base(4, 1); transition.table = {{c, d, 0, e}, {1, 0, 0, 0}, {c, d, 1, e}, {0, 0, 0, 1}}; base.table = {{b}, {a}, {Mint(a + b)}, {1}}; Matrix res = transition.pow(N - 1) * base; cout << res[2][0] << '\n'; } int main() { ios::sync_with_stdio(false); cin.tie(NULL); int t = 1; // cin >> t; while (t--) solve(); return 0; }