結果
| 問題 |
No.526 フィボナッチ数列の第N項をMで割った余りを求める
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2022-07-18 11:22:25 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 2 ms / 2,000 ms |
| コード長 | 3,462 bytes |
| コンパイル時間 | 4,325 ms |
| コンパイル使用メモリ | 264,540 KB |
| 最終ジャッジ日時 | 2025-01-30 10:46:15 |
|
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 12 |
ソースコード
#include <bits/stdc++.h>
#include <atcoder/all>
using namespace std;
#define ll long long
#define ull unsigned long long
#define rep(i, n) for (decltype(n) i = 0; i < (n); i++)
#define rep1(i, n) for (decltype(n) i = 1; i <= (n); i++)
#define repr(i, n) for (decltype(n) i = (n)-1; i >= 0; i--)
#define repr1(i, n) for (decltype(n) i = (n); i > 0; i--)
auto chmax = [](auto& a, auto b) {bool ret=a<b; if(ret)a=b; return ret; };
auto chmin = [](auto& a, auto b) {bool ret=a>b; if(ret)a=b; return ret; };
template <typename T> using pq_inv = priority_queue<T, vector<T>, greater<T>>;
vector<int> dd4={1, 0, -1, 0, 1}; // 4方位 rep(i,4) nh=h+dd4[i]; nw=w+dd4[i+1];
vector<int> dd8={1, 0, -1, 0, 1, 1,-1, -1, 1}; // 8方位 rep(i,8) nh=h+dd8[i]; nw=w+dd8[i+1];
template <typename T>
struct Matrix{
vector<vector<T>> mat;
vector<vector<T>> tmp;
int row=0,col=0;
Matrix(vector<vector<T>>& M) {
mat=M;
row=M.size();
col=M[0].size();
tmp.resize(row,vector<T>(col));
}
Matrix(int r, int c, int x=0) {
mat=vector(r,vector<T>(c,x));
row=r;
col=c;
tmp.resize(row,vector<T>(col));
}
vector<T>& operator[](int i) {return mat[i];}
Matrix<T> operator*(int x){
tmp.assign(row, vector<T>(col));
for(int i=0; i<row; i++){
for(int j=0; j<col; j++){
tmp[i][j]=x*mat[i][j];
}
}
return tmp;
}
Matrix<T> operator+(Matrix& M){
tmp.assign(row, vector<T>(col));
for(int i=0; i<row; i++){
for(int j=0; j<col; j++){
tmp[i][j]=M[i][j]+mat[i][j];
}
}
return tmp;
}
Matrix dot(Matrix& M){
assert (M.col==this->row);
tmp.assign(row, vector<T>(col));
for(int i=0; i<M.row; i++){
for(int j=0;j<this->col; j++){
for(int k=0; k<M.col; k++) tmp[i][j]+= M[i][k]*mat[k][j];
}
}
return tmp;
}
Matrix dot(Matrix& M, int mod){
assert (M.col==this->row);
tmp.assign(row, vector<T>(col));
for(int i=0; i<M.row; i++){
for(int j=0;j<this->col; j++){
for(int k=0; k<M.col; k++) tmp[i][j]= (tmp[i][j] + M[i][k]*mat[k][j]) %mod;
}
}
return tmp;
}
Matrix pow(int p){
assert (row==col);
Matrix x=mat;
Matrix ret(row, col);
for(int i=0; i<row; i++)ret[i][i]=1;
while(p>0){
if(p&1) ret = ret.dot(x);
x = x.dot(x);
p>>=1;
}
return ret;
}
Matrix pow(int p, int mod){
assert (row==col);
Matrix x=mat;
Matrix ret(row, col);
for(int i=0; i<row; i++)ret[i][i]=1;
while(p>0){
if(p&1) ret = ret.dot(x, mod);
x = x.dot(x, mod);
p>>=1;
}
return ret;
}
void print(){
for(int i=0; i<row; i++){
for(int j=0; j<col; j++){
printf("%*d",3,mat[i][j]);
}
printf("\n");
}
}
};
void solve(){
int N,M; cin >> N>>M;
vector<vector<ll>> A={{0,1},{1,1}} ;
Matrix mat(A);
mat = mat.pow(N-2,M);
cout << (mat[0][0] + mat[0][1])%M << endl;
}
int main() {
std::cin.tie(nullptr);
int T;
// cin >> T;
T=1;
for(int i=0; i<T; i++){
// solve(i);
solve();
}
return 0;
}