結果
問題 | No.526 フィボナッチ数列の第N項をMで割った余りを求める |
ユーザー | nawawan |
提出日時 | 2021-02-09 20:15:22 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 2 ms / 2,000 ms |
コード長 | 6,143 bytes |
コンパイル時間 | 899 ms |
コンパイル使用メモリ | 81,048 KB |
実行使用メモリ | 6,944 KB |
最終ジャッジ日時 | 2024-07-07 02:24:05 |
合計ジャッジ時間 | 1,289 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 1 ms
6,812 KB |
testcase_01 | AC | 2 ms
6,940 KB |
testcase_02 | AC | 1 ms
6,940 KB |
testcase_03 | AC | 2 ms
6,944 KB |
testcase_04 | AC | 2 ms
6,940 KB |
testcase_05 | AC | 2 ms
6,940 KB |
testcase_06 | AC | 1 ms
6,944 KB |
testcase_07 | AC | 1 ms
6,940 KB |
testcase_08 | AC | 2 ms
6,944 KB |
testcase_09 | AC | 2 ms
6,940 KB |
testcase_10 | AC | 2 ms
6,944 KB |
testcase_11 | AC | 1 ms
6,940 KB |
testcase_12 | AC | 2 ms
6,940 KB |
testcase_13 | AC | 1 ms
6,940 KB |
testcase_14 | AC | 2 ms
6,940 KB |
ソースコード
#include <iostream> #include <vector> #include <algorithm> #include <cassert> using namespace std; template<typename T> struct mat{ int N, M;//N x Mの行列(通常はN = M) vector<vector<T>> matrix;//行列 mat() : N(0), M(0), matrix(0){} mat(int n, int m){ N = n; M = m; matrix.resize(N, vector<T>(M)); } mat(vector<vector<T>> m){ N = m.size(); M = m[0].size(); matrix = m; } mat(int n, int m, vector<vector<T>> m1){ N = n; M = m; matrix = m1; } void init(vector<vector<T>> m){ N = m.size(); M = m[0].size(); matrix = m; } mat mulmod(const mat &mat2, const T MOD){ mat res(N, M); for(int i = 0; i < N; i++){ for(int j = 0; j < N; j++){ for(int k = 0; k < M; k++){ res.matrix[i][j] += (*this).matrix[i][k] * mat2.matrix[k][j] % MOD; if(res.matrix[i][j] >= MOD) res -= MOD; } } } return res; } vector<T> operate(vector<T> vec){ assert(vec.size() == M); vector<T> res(N); for(int i = 0; i < N; i++){ for(int j = 0; j < M; j++) res[i] += matrix[i][j] * vec[j]; } return res; } vector<T> operate(vector<T> vec, const T MOD){ assert(vec.size() == M); vector<T> res(N); for(int i = 0; i < N; i++){ for(int j = 0; j < M; j++){ res[i] += matrix[i][j] * vec[j] % MOD; if(res[i] >= MOD) res[i] -= MOD; } } return res; } vector<T> repow(T K, vector<T> vec){//行列累乗(MODなし) assert(N == M);//正方行列である必要あり while(K > 0){ if(K & 1) vec = operate(vec); vector<vector<T>> temp(N, vector<T>(M)); for(int i = 0; i < N; i++){ for(int j = 0; j < N; j++){ for(int k = 0; k < N; k++){ temp[i][j] += matrix[i][k] * matrix[k][j]; } } } matrix.swap(temp); K >>= 1; } return vec; } vector<T> repow(T K, vector<T> vec, const T MOD){//行列累乗(MODあり) assert(N == M); while(K > 0){ if(K & 1) vec = operate(vec, MOD); vector<vector<T>> temp(N, vector<T>(M)); for(int i = 0; i < N; i++){ for(int j = 0; j < N; j++){ for(int k = 0; k < N; k++){ temp[i][j] += matrix[i][k] * matrix[k][j] % MOD; if(temp[i][j] >= MOD) temp[i][j] -= MOD; } } } matrix.swap(temp); K >>= 1; } return vec; } vector<vector<T>> repow(T K, vector<vector<T>> m, const T MOD){//行列累乗(MODあり)単位行列とかとかける assert(N == M && m.size() == N && m[0].size() == M); mat m1(m); while(K > 0){ if(K & 1) m1 = mulmod(m1, MOD); vector<vector<T>> temp(N, vector<T>(M)); for(int i = 0; i < N; i++){ for(int j = 0; j < N; j++){ for(int k = 0; k < N; k++){ temp[i][j] += matrix[i][k] * matrix[k][j] % MOD; if(temp[i][j] >= MOD) temp[i][j] -= MOD; } } } matrix.swap(temp); K >>= 1; } return m1.matrix; } mat operator+(const vector<vector<T>> &mat2){ mat res(N, M); for(int i = 0; i < N; i++){ for(int j = 0; j < M; j++) res.matrix[i][j] = (*this).matrix[i][j] + mat2[i][j]; } return res; } mat operator+(const mat &mat1){ mat res(N, M); for(int i = 0; i < N; i++){ for(int j = 0; j < M; j++) res.matrix[i][j] = (*this).matrix[i][j] + mat1.matrix[i][j]; } return res; } mat operator-(const mat &mat1){ mat res(N, M); for(int i = 0; i < N; i++){ for(int j = 0; j < M; j++) res.matrix[i][j] = (*this).matrix[i][j] - mat1.matrix[i][j]; } return res; } mat operator-( const vector<vector<T>> &mat2){ mat res(N, M); for(int i = 0; i < N; i++){ for(int j = 0; j < M; j++) res.matrix[i][j] = (*this).matrix[i][j] - mat2[i][j]; } return res; } mat operator*(const mat &mat2){ mat res(N, M); for(int i = 0; i < N; i++){ for(int j = 0; j < N; j++){ for(int k = 0; k < M; k++){ res.matrix[i][j] += (*this).matrix[i][k] * mat2.matrix[k][j]; } } } return res; } mat& operator+=(const mat &mat2){ assert(N == mat2.N && M == mat2.M); for(int i = 0; i < N; i++){ for(int j = 0; j < M; j++) (*this).matrix[i][j] += mat2.matrix[i][j]; } return *this; } mat& operator-=(const mat &mat2){ assert(N == mat2.N && M == mat2.M); for(int i = 0; i < N; i++){ for(int j = 0; j < M; j++) (*this).matrix[i][j] -= mat2.matrix[i][j]; } return *this; } mat& operator+=(const vector<vector<T>> &mat2){ assert(N == mat2.size() && M == mat2[0].size()); for(int i = 0; i < N; i++){ for(int j = 0; j < M; j++) (*this).matrix[i][j] += mat2[i][j]; } return *this; } mat& operator-=(const vector<vector<T>> &mat2){ assert(N == mat2.size() && M == mat2[0].size()); for(int i = 0; i < N; i++){ for(int j = 0; j < M; j++) (*this).matrix[i][j] -= mat2[i][j]; } return *this; } }; int main(){ long long N, M; cin >> N >> M; mat<long long> m1; vector<vector<long long>> gyo = {{1, 1}, {1, 0}}; m1.init(gyo); vector<long long> fir = {1, 0}; vector<long long> ans = m1.repow(N - 1, fir, M); cout << ans[1] << endl; }