#define PROBLEM "https://yukicoder.me/problems/no/1136" #include #include #include #include #include namespace mtd { template class Matrix { int h, w; std::vector> mat; public: Matrix(const std::vector>& mat) : h(mat.size()), w(mat[0].size()), mat(mat) {} inline static auto identity(int size) { std::vector> ret(size, std::vector(size)); for (int i = 0; i < size; ++i) { ret[i][i] = 1; } return Matrix(ret); } auto begin() const { return mat.begin(); } auto end() const { return mat.end(); } const auto& operator[](int i) const { return mat[i]; } auto& operator[](int i) { return mat[i]; } auto operator*(const Matrix& tgt) const { assert(w == tgt.h); std::vector> ret(h, std::vector(tgt.w)); for (int i = 0; i < h; ++i) for (int j = 0; j < tgt.w; ++j) { for (int k = 0; k < w; ++k) { ret[i][j] += mat[i][k] * tgt[k][j]; } } return Matrix(ret); } auto pow(long long n) const { assert(h == w); auto ret = identity(h); auto now = *this; while (n) { if (n & 1) { ret = ret * now; } n >>= 1; now = now * now; } return ret; } };} namespace mtd { template class Math { const std::vector m_fac; const std::vector m_finv; auto constructFac(int s) { std::vector fac(s); fac[0] = fac[1] = 1; for (long long i = 2; i < s; ++i) { fac[i] = fac[i - 1] * i; } return fac; } auto constructInv(int s) { std::vector finv(s); finv[s - 1] = 1 / m_fac[s - 1]; for (long long i = s - 2; i >= 0; --i) { finv[i] = finv[i + 1] * (i + 1); } return finv; } public: constexpr Math(long long size = 3 * 1e6) : m_fac(constructFac(size)), m_finv(constructInv(size)) {} static constexpr T pow(T a, long long b) { T ans = 1; while (b > 0) { if (b & 1) { ans *= a; } b >>= 1; a *= a; } return ans; } constexpr auto fact(int n) const { return (n < 0) ? 0 : m_fac[n]; } constexpr auto factInv(int n) const { return (n < 0 ? 0 : m_finv[n]); } constexpr auto comb(int n, int r) const { return fact(n) * factInv(r) * factInv(n - r); } constexpr auto perm(int n, int r) const { return fact(n) * factInv(n - r); } };} namespace mtd { template class ModInt { public: T x; constexpr ModInt(T x) : x(x >= 0 ? x % MOD : MOD + (x % MOD)) {} constexpr ModInt() : ModInt(0) {} constexpr auto& operator+=(const ModInt& m) { x += m.x; if (x >= MOD) { x -= MOD; } return *this; } constexpr auto& operator-=(const ModInt& m) { x -= m.x; if (x < 0) { x += MOD; } return *this; } constexpr auto& operator*=(const ModInt& m) { x *= m.x; if (x >= MOD) { x %= MOD; } return *this; } constexpr auto& operator/=(const ModInt& m) { x *= mtd::Math>::pow(m.x, MOD - 2).x; if (x >= MOD) { x %= MOD; } return *this; } constexpr auto operator+(const ModInt& m) const { auto t = *this; t += m; return t; } constexpr auto operator-(const ModInt& m) const { auto t = *this; t -= m; return t; } constexpr auto operator*(const ModInt& m) const { auto t = *this; t *= m; return t; } constexpr auto operator/(const ModInt& m) const { auto t = *this; t /= m; return t; } constexpr auto& operator+=(const T& t) { return *this += ModInt(t); } constexpr auto& operator-=(const T& t) { return *this -= ModInt(t); } constexpr auto& operator*=(const T& n) { return *this *= ModInt(n); } constexpr auto& operator/=(const T& n) { return *this /= ModInt(n); } constexpr auto operator+(const T& t) const { return *this + ModInt(t); } constexpr auto operator-(const T& t) const { return *this - ModInt(t); } constexpr auto operator*(const T& t) const { return *this * ModInt(t); } constexpr auto operator/(const T& t) const { return *this / ModInt(t); } constexpr friend auto operator+(const T& t, const ModInt& m) { return m + t; } constexpr friend auto operator-(const T& t, const ModInt& m) { return -m + t; } constexpr friend auto operator*(const T& t, const ModInt& m) { return m * t; } constexpr friend auto operator/(const T& t, const ModInt& m) { return ModInt(1) / m * t; } constexpr auto operator-() const { return ModInt(0 - x); } constexpr auto operator!=(const ModInt& m) const { return x != m.x; } constexpr auto operator==(const ModInt& m) const { return !(x != m.x); } constexpr friend std::ostream& operator<<(std::ostream& os, const ModInt& m) { return os << m.x; } constexpr friend std::istream& operator>>(std::istream& is, ModInt& m) { return is >> m.x; } constexpr auto val() const { return x; } };} signed main() { std::cin.tie(0); std::ios::sync_with_stdio(0); constexpr long long MOD = 1e9 + 7; using mint = mtd::ModInt; long long n; std::cin >> n; mtd::Matrix mat({{-1, 1}, {0, 3}}); auto mat_p = mat.pow(n); mint ans = mat_p[0][0] + mat_p[0][1]; std::cout << ans << std::endl; }