結果

問題 No.3228 Very Large Fibonacci Sum
ユーザー a01sa01to
提出日時 2025-08-20 00:31:34
言語 C++23
(gcc 13.3.0 + boost 1.87.0)
結果
WA  
実行時間 -
コード長 12,553 bytes
コンパイル時間 2,957 ms
コンパイル使用メモリ 282,464 KB
実行使用メモリ 7,716 KB
最終ジャッジ日時 2025-08-20 00:31:38
合計ジャッジ時間 4,237 ms
ジャッジサーバーID
(参考情報)
judge1 / judge3
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 22 WA * 1
権限があれば一括ダウンロードができます

ソースコード

diff #

#line 1 "main.cpp"
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (n); ++i)
using ll = long long;
using ull = unsigned long long;
#line 2 "my-library\\library\\data-structure\\matrix.hpp"
#line 4 "my-library\\library\\data-structure\\matrix.hpp"
#include <concepts>
#line 7 "my-library\\library\\data-structure\\matrix.hpp"
using namespace std;
#line 2 "my-library\\library\\_internal\\types.hpp"
#line 4 "my-library\\library\\_internal\\types.hpp"
using namespace std;
#line 2 "my-library\\library\\_internal\\modint-base.hpp"
#include <type_traits>
using namespace std;
namespace asalib::_internal {
  class modint_base {};
  template<typename T>
  concept is_modint = is_base_of_v<modint_base, T>;
}
#line 7 "my-library\\library\\_internal\\types.hpp"
namespace asalib::_internal {
  template<class T>
  concept integral_like = integral<T> || is_modint<T>;
  template<class T>
  concept floating_like = floating_point<T>;
  template<class T>
  concept numeric_like = integral_like<T> || floating_like<T>;
  template<class T>
  T plus(T a, T b) { return a + b; }
  template<class T>
  T minus(T a, T b) { return a - b; }
  template<class T>
  T zero() { return 0; }
}
#line 10 "my-library\\library\\data-structure\\matrix.hpp"
namespace asalib::matrix {
  template<_internal::numeric_like T>
  class Matrix {
    public:
    constexpr Matrix(): _n_row(0), _n_col(0) {};
    constexpr Matrix(size_t n_row, size_t n_col): _n_row(n_row), _n_col(n_col) {
      _data.resize(n_row, valarray<T>(n_col));
    };
    constexpr Matrix(size_t n_row, size_t n_col, T x): _n_row(n_row), _n_col(n_col) {
      _data.resize(n_row, valarray<T>(x, n_col));
    };
    constexpr T& at(size_t i, size_t j) {
      assert(i < _n_row);
      assert(j < _n_col);
      return _data[i][j];
    }
    constexpr T at(size_t i, size_t j) const {
      assert(i < _n_row);
      assert(j < _n_col);
      return _data[i][j];
    }
    constexpr Matrix& operator+=(const T& x) {
      _data += x;
      return *this;
    }
    constexpr Matrix& operator-=(const T& x) {
      _data -= x;
      return *this;
    }
    constexpr Matrix& operator*=(const T& x) {
      _data *= x;
      return *this;
    }
    constexpr Matrix& operator/=(const T& x) {
      _data /= x;
      return *this;
    }
    constexpr Matrix& operator%=(const T& x) {
      _data %= x;
      return *this;
    }
    constexpr Matrix operator+(const T& x) const { return Matrix(*this) += x; }
    constexpr Matrix operator-(const T& x) const { return Matrix(*this) -= x; }
    constexpr Matrix operator*(const T& x) const { return Matrix(*this) *= x; }
    constexpr Matrix operator/(const T& x) const { return Matrix(*this) /= x; }
    constexpr Matrix operator%(const T& x) const { return Matrix(*this) %= x; }
    constexpr Matrix& operator+=(const Matrix& x) {
      assert(_n_row == x._n_row);
      assert(_n_col == x._n_col);
      _data += x._data;
      return *this;
    }
    constexpr Matrix& operator-=(const Matrix& x) {
      assert(_n_row == x._n_row);
      assert(_n_col == x._n_col);
      _data -= x._data;
      return *this;
    }
    constexpr Matrix& operator*=(const Matrix& x) {
      assert(_n_col == x._n_row);
      Matrix res(_n_row, x._n_col);
      for (size_t i = 0; i < _n_row; ++i) {
        for (size_t k = 0; k < _n_col; ++k) {
          for (size_t j = 0; j < x._n_col; ++j) {
            res._data[i][j] += _data[i][k] * x._data[k][j];
          }
        }
      }
      return *this = res;
    }
    constexpr Matrix operator+(const Matrix& x) const { return Matrix(*this) += x; }
    constexpr Matrix operator-(const Matrix& x) const { return Matrix(*this) -= x; }
    constexpr Matrix operator*(const Matrix& x) const { return Matrix(*this) *= x; }
    constexpr bool operator==(const Matrix& x) const { return _n_row == x._n_row && _n_col == x._n_col && _data == x._data; }
    constexpr bool operator!=(const Matrix& x) const { return !(*this == x); }
    constexpr bool operator<(const Matrix& x) const { return _data < x._data; }
    constexpr Matrix transpose() const {
      Matrix res(_n_col, _n_row);
      for (size_t i = 0; i < _n_row; ++i) {
        for (size_t j = 0; j < _n_col; ++j) {
          res._data[j][i] = _data[i][j];
        }
      }
      return res;
    }
    template<integral U>
    constexpr Matrix pow(U x) const {
      assert(_n_row == _n_col);
      Matrix res = I(_n_row);
      Matrix a(*this);
      while (x) {
        if (x & 1) res *= a;
        a *= a;
        x >>= 1;
      }
      return res;
    }
    static constexpr Matrix I(size_t n) {
      Matrix res(n, n);
      for (size_t i = 0; i < n; ++i) {
        res._data[i][i] = 1;
      }
      return res;
    }
    constexpr size_t n_row() const { return _n_row; }
    constexpr size_t n_col() const { return _n_col; }
    private:
    size_t _n_row, _n_col;
    valarray<valarray<T>> _data;
    public:
    constexpr T determinant() const;
    template<_internal::numeric_like U>
    constexpr U determinant() const;
  };
}
#line 2 "my-library\\library\\data-structure\\modint.hpp"
#line 8 "my-library\\library\\data-structure\\modint.hpp"
using namespace std;
#line 2 "my-library\\library\\math\\extgcd.hpp"
#line 4 "my-library\\library\\math\\extgcd.hpp"
#include <optional>
#line 6 "my-library\\library\\math\\extgcd.hpp"
using namespace std;
namespace asalib::math {
  template<integral T>
  constexpr optional<pair<T, T>> extgcd(T a, T b, T c) {
    if (b == 0) {
      if (c % a != 0) return nullopt;
      return make_pair(c / a, 0);
    }
    auto res = extgcd(b, a % b, c);
    if (!res) return nullopt;
    auto [x, y] = *res;
    return make_pair(y, x - (a / b) * y);
  }
}
#line 12 "my-library\\library\\data-structure\\modint.hpp"
namespace asalib::ds {
  template<unsigned int mod>
    requires(mod >= 1)
  class static_modint: _internal::modint_base {
    using mint = static_modint;
    using uint = unsigned int;
    using ll = long long;
    using ull = unsigned long long;
    public:
    constexpr static_modint(): _val(0) {};
    template<integral T>
    constexpr static_modint(const T& x) {
      if constexpr (is_signed_v<T>) {
        ll y = x % static_cast<ll>(mod);
        if (y < 0) y += mod;
        _val = y;
      }
      else {
        _val = x % mod;
      }
    }
    friend constexpr mint operator+(const mint& l, const mint& r) { return mint(l) += r; }
    friend constexpr mint operator-(const mint& l, const mint& r) { return mint(l) -= r; }
    friend constexpr mint operator*(const mint& l, const mint& r) { return mint(l) *= r; }
    friend constexpr mint operator/(const mint& l, const mint& r) { return mint(l) /= r; }
    constexpr mint operator+() const { return *this; }
    constexpr mint operator-() const { return 0 - *this; }
    constexpr mint& operator+=(const mint& other) {
      _val += other._val;
      if (_val >= mod) _val -= mod;
      return *this;
    }
    constexpr mint& operator-=(const mint& other) {
      _val -= other._val;
      if (_val >= mod) _val += mod;
      return *this;
    }
    constexpr mint& operator*=(const mint& other) {
      ull z = _val;
      z *= other._val;
      _val = z % mod;
      return *this;
    }
    constexpr mint& operator/=(const mint& other) { return *this = *this * other.inv(); }
    constexpr mint& operator++() {
      _val++;
      if (_val == mod) _val = 0;
      return *this;
    }
    constexpr mint& operator--() {
      if (_val == 0) _val = mod;
      _val--;
      return *this;
    }
    constexpr mint operator++(int) {
      mint res = *this;
      ++*this;
      return res;
    }
    constexpr mint operator--(int) {
      mint res = *this;
      --*this;
      return res;
    }
    constexpr bool operator==(const mint& r) const { return _val == r._val; }
    constexpr bool operator!=(const mint& r) const { return _val != r._val; }
    constexpr bool operator<(const mint& r) const { return _val < r._val; }
    template<integral T>
    constexpr mint pow(T x) const {
      assert(x >= 0);
      mint res = 1, base = *this;
      while (x) {
        if (x & 1) res *= base;
        base *= base;
        x >>= 1;
      }
      return res;
    }
    constexpr mint inv() const {
      if constexpr (is_prime_mod) return pow(mod - 2);
      else {
        if (gcd(_val, mod) != 1) throw invalid_argument("Modular inverse does not exist");
        return mint(math::extgcd<long long>(_val, mod, 1).value().first);
      }
    }
    constexpr unsigned int val() const { return _val; }
    private:
    uint _val;
    static constexpr bool is_prime_mod = []() {
      for (unsigned int i = 2; i * i <= mod; ++i) {
        if (mod % i == 0) return false;
      }
      return true;
    }();
  };
  template<unsigned int _id>
  class dynamic_modint: _internal::modint_base {
    using mint = dynamic_modint;
    using uint = unsigned int;
    using ll = long long;
    using ull = unsigned long long;
    public:
    constexpr dynamic_modint(): _val(0) {}
    template<integral T>
    constexpr dynamic_modint(const T& x) {
      assert(_mod >= 1);
      if constexpr (is_signed_v<T>) {
        ll y = x % static_cast<ll>(_mod);
        if (y < 0) y += _mod;
        _val = y;
      }
      else {
        _val = x % _mod;
      }
    };
    friend constexpr auto operator+(const mint& l, const mint& r) -> mint { return mint(l) += r; }
    friend constexpr mint operator-(const mint& l, const mint& r) { return mint(l) -= r; }
    friend constexpr mint operator*(const mint& l, const mint& r) { return mint(l) *= r; }
    friend constexpr mint operator/(const mint& l, const mint& r) { return mint(l) /= r; }
    constexpr mint operator+() const { return *this; }
    constexpr mint operator-() const { return 0 - *this; }
    constexpr mint& operator+=(const mint& other) {
      _val += other._val;
      if (_val >= _mod) _val -= _mod;
      return *this;
    }
    constexpr mint& operator-=(const mint& other) {
      _val -= other._val;
      if (_val >= _mod) _val += _mod;
      return *this;
    }
    constexpr mint& operator*=(const mint& other) {
      ull z = _val;
      z *= other._val;
      _val = z % _mod;
      return *this;
    }
    constexpr mint& operator/=(const mint& other) { return *this = *this * other.inv(); }
    constexpr mint& operator++() {
      _val++;
      if (_val == _mod) _val = 0;
      return *this;
    }
    constexpr mint& operator--() {
      if (_val == 0) _val = _mod;
      _val--;
      return *this;
    }
    constexpr mint operator++(int) {
      mint res = *this;
      ++*this;
      return res;
    }
    constexpr mint operator--(int) {
      mint res = *this;
      --*this;
      return res;
    }
    constexpr bool operator==(const mint& r) const { return _val == r._val; }
    constexpr bool operator!=(const mint& r) const { return _val != r._val; }
    constexpr bool operator<(const mint& r) const { return _val < r._val; }
    template<integral T>
    constexpr mint pow(T x) const {
      assert(x >= 0);
      mint res = 1, base = *this;
      while (x) {
        if (x & 1) res *= base;
        base *= base;
        x >>= 1;
      }
      return res;
    }
    constexpr mint inv() const {
      if (gcd(_val, _mod) != 1) throw invalid_argument("Modular inverse does not exist");
      return mint(math::extgcd<long long>(_val, _mod, 1).value().first);
    }
    constexpr uint val() const { return _val; }
    constexpr static uint mod() { return _mod; }
    constexpr static void set_mod(const uint mod) {
      assert(mod >= 1);
      _mod = mod;
    }
    private:
    uint _val;
    static inline uint _mod;
  };
}
#line 9 "main.cpp"
using mint = asalib::ds::static_modint<1000000007>;
int main() {
  cin.tie(nullptr)->sync_with_stdio(false);
  ll a, b, c, d, e, n;
  cin >> a >> b >> c >> d >> e >> n;
  if (n == 0) {
    cout << a << '\n';
    return 0;
  }
  asalib::matrix::Matrix<mint> M(5, 5);
  M.at(0, 0) = 1, M.at(0, 1) = c, M.at(0, 2) = d, M.at(0, 3) = 0, M.at(0, 4) = e;
  M.at(1, 0) = 0, M.at(1, 1) = c, M.at(1, 2) = d, M.at(1, 3) = 0, M.at(1, 4) = e;
  M.at(2, 0) = 0, M.at(2, 1) = 1, M.at(2, 2) = 0, M.at(2, 3) = 0, M.at(2, 4) = 0;
  M.at(3, 0) = 0, M.at(3, 1) = 0, M.at(3, 2) = 1, M.at(3, 3) = 0, M.at(3, 4) = 0;
  M.at(4, 0) = 0, M.at(4, 1) = 0, M.at(4, 2) = 0, M.at(4, 3) = 0, M.at(4, 4) = 1;
  asalib::matrix::Matrix<mint> init(5, 1);
  init.at(0, 0) = a + b, init.at(1, 0) = b, init.at(2, 0) = a, init.at(3, 0) = 0, init.at(4, 0) = 1;
  cout << (M.pow(n - 1) * init).at(0, 0).val() << '\n';
  return 0;
}
0