結果
| 問題 | No.526 フィボナッチ数列の第N項をMで割った余りを求める |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-12-11 21:26:05 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.89.0) |
| 結果 |
AC
|
| 実行時間 | 2 ms / 2,000 ms |
| コード長 | 4,578 bytes |
| 記録 | |
| コンパイル時間 | 2,109 ms |
| コンパイル使用メモリ | 204,864 KB |
| 実行使用メモリ | 7,848 KB |
| 最終ジャッジ日時 | 2025-12-11 21:26:09 |
| 合計ジャッジ時間 | 3,409 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 12 |
ソースコード
// #define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;
using ll = long long; const int inf = INT_MAX / 2; const ll infl = 1LL << 60;
int mod;
class mint {
long long x;
public:
mint(long long x = 0): x((x % mod + mod) % mod) {}
mint operator-() const {
return mint(-x);
}
mint& operator+=(const mint &a) {
if ((x += a.x) >= mod) x -= mod;
return (*this);
}
mint& operator-=(const mint &a) {
if ((x += mod-a.x) >= mod) x -= mod;
return (*this);
}
mint& operator*=(const mint &a) {
(x *= a.x) %= mod;
return (*this);
}
mint operator+(const mint &a) const {
mint res(*this);
return res += a;
}
mint operator-(const mint &a) const {
mint res(*this);
return res -= a;
}
mint operator*(const mint &a) const {
mint res(*this);
return res *= a;
}
mint pow(ll t) const {
if (!t) return 1;
mint a = pow(t >> 1);
a *= a;
if (t & 1) a *= (*this);
return a;
}
// for prime mod
mint inv() const {
return pow(mod - 2);
}
mint& operator/=(const mint &a) {
return (*this) *= a.inv();
}
mint operator/(const mint &a) {
mint res(*this);
return res /= a;
}
friend ostream& operator<<(ostream& os, const mint &m) {
os << m.x;
return os;
}
};
template <typename T>
class Matrix {
private:
vector<vector<T>> A;
public:
Matrix(){}
Matrix(size_t n): A(n, vector<T>(n, T{})){ assert(n > 0); }
Matrix(size_t h, size_t w): A(h, vector<T>(w, T{})){ assert(h > 0 && w > 0); }
size_t getHeight() const {
return A.size();
}
size_t getWidth() const {
assert(!A.empty());
return A[0].size();
}
// when you read the item
inline const vector<T> &operator[](size_t k) const {
return A.at(k);
}
// when you assign the item
inline vector<T> &operator[](size_t k){
return A.at(k);
}
// Matrix I = Matrix<int>::I(n);
static Matrix I(size_t n){
Matrix mat_I(n);
for(size_t i=0; i<n; ++i){
mat_I[i][i] = T{1};
}
return mat_I;
}
Matrix &operator+=(const Matrix &B){
size_t h = getHeight(), w = getWidth();
assert(h == B.getHeight() && w == B.getWidth());
for(size_t i=0; i<h; ++i) for(size_t j=0; j<w; ++j) (*this)[i][j] += B[i][j];
return (*this);
}
Matrix &operator-=(const Matrix &B){
size_t h = getHeight(), w = getWidth();
assert(h == B.getHeight() && w == B.getWidth());
for(size_t i=0; i<h; ++i) for(size_t j=0; j<w; ++j) (*this)[i][j] -= B[i][j];
return (*this);
}
Matrix &operator*=(const Matrix &B){
size_t h = getHeight(), w = B.getWidth(), p = getWidth();
assert(p == B.getHeight());
vector<vector<T>> C(h, vector<T>(w, 0));
for(size_t i=0; i<h; ++i)
for(size_t j=0; j<w; ++j)
for(size_t k=0; k<p; ++k)
C[i][j] += (*this)[i][k] * B[k][j];
A.swap(C);
return (*this);
}
Matrix &operator^=(long long k){
size_t h = getHeight();
size_t w = getWidth();
assert(h == w && k >= 0);
Matrix B = Matrix::I(h);
while(k > 0){
if(k & 1) B *= (*this);
(*this) *= (*this);
k >>= 1;
}
A.swap(B.A);
return (*this);
}
Matrix operator+(const Matrix &B) const {
return (Matrix(*this) += B);
}
Matrix operator-(const Matrix &B) const {
return (Matrix(*this) -= B);
}
Matrix operator*(const Matrix &B) const {
return (Matrix(*this) *= B);
}
Matrix operator^(const long long k) const {
return (Matrix(*this) ^= k);
}
friend ostream &operator<<(ostream &os, const Matrix &p){
size_t h = p.getHeight();
size_t w = p.getWidth();
for(size_t i=0; i<h; ++i){
for(size_t j=0; j<w; ++j){
os << p[i][j] << (j == w-1 ? "\n" : ", ");
}
}
return(os);
}
};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
ll n, m; cin >> n >> m;
mod = m;
Matrix<mint> F(2, 1);
Matrix<mint> M(2, 2);
F[0][0] = 0;
F[1][0] = 1;
M[0][0] = 1;
M[0][1] = 1;
M[1][0] = 1;
M[1][1] = 0;
M ^= (n-1);
Matrix<mint> ans = M * F;
cout << ans[0][0] << endl;
}