結果
問題 | No.526 フィボナッチ数列の第N項をMで割った余りを求める |
ユーザー | syak_18 |
提出日時 | 2020-01-22 16:53:13 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 2 ms / 2,000 ms |
コード長 | 5,799 bytes |
コンパイル時間 | 1,931 ms |
コンパイル使用メモリ | 179,984 KB |
実行使用メモリ | 6,944 KB |
最終ジャッジ日時 | 2024-07-08 08:31:36 |
合計ジャッジ時間 | 2,117 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1 ms
6,816 KB |
testcase_01 | AC | 2 ms
6,940 KB |
testcase_02 | AC | 1 ms
6,944 KB |
testcase_03 | AC | 2 ms
6,940 KB |
testcase_04 | AC | 1 ms
6,940 KB |
testcase_05 | AC | 2 ms
6,940 KB |
testcase_06 | AC | 1 ms
6,940 KB |
testcase_07 | AC | 2 ms
6,944 KB |
testcase_08 | AC | 2 ms
6,944 KB |
testcase_09 | AC | 1 ms
6,940 KB |
testcase_10 | AC | 2 ms
6,940 KB |
testcase_11 | AC | 1 ms
6,944 KB |
testcase_12 | AC | 1 ms
6,944 KB |
testcase_13 | AC | 2 ms
6,940 KB |
testcase_14 | AC | 1 ms
6,940 KB |
ソースコード
#include <bits/stdc++.h> using namespace std; typedef long long ll; class ModInt { using u64 = std::uint_fast64_t; static u64 &mod() { static u64 mod_ = 0; return mod_; } public: u64 x; ModInt(const ll x = 0) : x(x < 0 ? (mod() - (-x % mod())) % mod() : x % mod()) {} ModInt operator+(const ModInt r) { return ModInt(*this) += r; } ModInt operator*(const ModInt r) { return ModInt(*this) *= r; } ModInt operator-(const ModInt r) { return ModInt(*this) -= r; } ModInt operator/(const ModInt r) { return ModInt(*this) /= r; } ModInt operator-() { return ModInt(mod() - x); } ModInt &operator+=(const ModInt r) { x += r.x; if (x >= mod()) x -= mod(); return *this; } ModInt &operator-=(const ModInt r) { if (x < r.x) x += mod(); x -= r.x; return *this; } ModInt &operator*=(const ModInt r) { x *= r.x; if (x >= mod()) x %= mod(); return *this; } ModInt &operator/=(ModInt r) { if (!(x % r.x)) { x /= r.x; return *this; } u64 p = mod() - 2; while (p > 0) { if (p & 1) *this *= r; r *= r; p >>= 1; } return *this; } ModInt &operator++(int) { return (*this) += 1; } ModInt &operator++() { return (*this) += 1; } ModInt &operator--(int) { return (*this) -= 1; } ModInt &operator--() { return (*this) -= 1; } bool operator<(const ModInt r) { return x < r.x; } bool operator>(const ModInt r) { return x > r.x; } bool operator<=(const ModInt r) { return x <= r.x; } bool operator>=(const ModInt r) { return x >= r.x; } bool operator==(const ModInt r) { return x == r.x; } bool operator!=(const ModInt r) { return x != r.x; } ModInt inv() { return (ModInt)1 / (*this); } int get_mod() { return mod(); } friend std::istream &operator>>(std::istream &in, ModInt &m) { ll a; in >> a; if (a < 0) a = mod() - (-a % mod()); if (a >= mod()) a %= mod(); m.x = a; return in; } friend std::ostream &operator<<(std::ostream &out, const ModInt &m) { out << m.x; return out; } static void set_mod(const u64 m) { mod() = m; } }; using mint = ModInt; template <typename T> class Matrix { vector<vector<T>> mat; public: const size_t height, width; Matrix(size_t height, size_t width, T e = 0) : height(height), width(width) { mat.assign(height, vector<T>(width, e)); } Matrix(vector<vector<T>> m) : mat(m), height(m.size()), width(m[0].size()) {} Matrix operator+(const Matrix r) { return Matrix(*this) += r; } Matrix operator*(const Matrix r) { return Matrix(*this) *= r; } Matrix operator-(const Matrix r) { return Matrix(*this) -= r; } Matrix operator*(const T x) { return Matrix(*this) *= x; } Matrix operator-() { return Matrix(*this) *= -1; } Matrix &operator+=(const Matrix a) { assert(height == a.height && width == a.width); for (int i = 0; i < height; i++) for (int j = 0; j < width; j++) mat[i][j] += a[i][j]; return *this; } Matrix &operator-=(const Matrix a) { assert(height == a.height && width == a.width); for (int i = 0; i < height; i++) for (int j = 0; j < width; j++) mat[i][j] -= a[i][j]; return *this; } Matrix &operator*=(const Matrix a) { assert(width == a.height); vector<vector<T>> b(height, vector<T>(a.width, 0)); for (int i = 0; i < height; i++) for (int j = 0; j < a.width; j++) for (int k = 0; k < width; k++) b[i][j] += mat[i][k] * a[k][j]; mat.swap(b); return *this; } Matrix &operator*=(const T x) { for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { mat[i][j] *= x; } } } T det() { assert(height == width); Matrix b(*this); T res = 1; for (int i = 0; i < width; i++) { int idx = -1; for (int j = i; j < width; j++) { if (b[i][j] != 0) idx = j; } if (idx == -1) return 0; if (i != idx) { res *= -1; swap(b[i], b[idx]); } res *= b[i][i]; T x = b[i][i]; for (int j = 0; j < width; j++) { b[i][j] /= x; } for (int j = i + 1; j < width; j++) { T a = b[j][i]; for (int k = 0; k < width; k++) { b[i][k] -= b[i][k] * a; } } } return res; } vector<T> &operator[](int i) { return mat[i]; } const vector<T> &operator[](int i) const { return mat[i]; } friend std::ostream &operator<<(std::ostream &out, const Matrix &a) { for (int i = 0; i < a.height; i++) { out << "( "; for (int j = 0; j < a.width; j++) out << a[i][j] << (j + 1 == a.width ? " )\n" : ","); } return out; } static Matrix<T> I(size_t n) { Matrix<T> I(n, n); for (int i = 0; i < n; i++) I[i][i] = 1; return I; } }; template <typename T, typename U> T pow(T x, U n, T e = 1) { T res = e; while (n > 0) { if (n & 1) res *= x; x *= x; n >>= 1; } return res; } int main() { int n, m; cin >> n >> m; mint::set_mod(m); Matrix<mint> A({{0, 1}, {1, 1}}); vector<vector<mint>> v = {{0}, {1}}; Matrix<mint> B(v); Matrix<mint> I = Matrix<mint>::I(2); cout << (pow<Matrix<mint>, int>(A, n - 2, I) * B)[1][0] << endl; return 0; }