问题描述
用 fib(n) 表示斐波那契数列的第 n项,现在要求你求 fib(n) mod m。fib(1)=1,fib(2)=1。
输入格式
输入 2 个整数 n(1≤n≤10^18 ),m(2≤m≤100000000)。
输出格式
输出 fib(n) 对 m 取模的值。
样例输入
100000000 100000000
样例输出
60546875
AC代码
#include<iostream>
#include<cmath>
using namespace std;
typedef long long ll;
int n=2; // 所有矩阵都是 n * n 的矩阵
struct matrix {
ll a[100][100];
};
matrix matrix_mul(matrix A, matrix B, int mod) {
// 2 个矩阵相乘
matrix C;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
C.a[i][j] = 0;
for (int k = 1; k <= n; ++k) {
C.a[i][j] += A.a[i][k] * B.a[k][j] % mod;
C.a[i][j] %= mod;
}
}
}
return C;
}
matrix unit() {
// 返回一个单位矩阵
matrix res;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
if (i == j) {
res.a[i][j] = 1;
} else {
res.a[i][j] = 0;
}
}
}
return res;
}
matrix matrix_pow(matrix A, long long n, int mod) {
// 快速求矩阵 A 的 n 次方
matrix res = unit(), temp = A;
for (; n; n /= 2) {
if (n & 1) {
res = matrix_mul(res, temp, mod);
//cout<<res.a[1][1]<<" "<<res.a[1][2]<<endl<<res.a[2][1]<<" "<<res.a[2][2]<<endl;
}
temp = matrix_mul(temp, temp, mod);
}
return res;
}
matrix mul(matrix a,matrix b,int mod)
{
matrix C;
for (int i = 1; i <= 2; ++i) {
for (int j = 1; j <= 2; ++j) {
C.a[i][j] = 0;
for (int k = 1; k <= 1; ++k) {
C.a[i][j] += a.a[i][k] * b.a[k][j];
C.a[i][j]%=mod;
}
}
}
return C;
}
ll fib(ll n,ll mod)
{
matrix res;
res.a[1][1]=1;
res.a[1][2]=1;
res.a[2][1]=1;
res.a[2][2]=0;
res=matrix_pow(res,n-1,mod);
matrix rr;
rr.a[1][1]=1;
rr.a[2][1]=1;
rr=mul(rr,res,mod);
cout<<rr.a[2][1];
}
int main()
{
ll m,n;
cin>>m>>n;
fib(m,n);
return 0;
}