题意
大家都知道 Fibonacci 数列吧,$f_1=1,f_2=1,f_3=2,f_4=3,…,f_n=f_{n−1}+f_{n−2}$。
现在问题很简单,输入 $n$ 和 $m$,求 ${f_n}$ 的前 $n$ 项和 $S_n \bmod m$。
输入格式
共一行,包含两个整数 $n$ 和 $m$。
输出格式
输出前 $n$ 项和 $S_n \bmod m$ 的值。
数据范围
$1 \le n \le 2000000000$,
$1 \le m \le 1000000010$
输入样例:
5 1000
输出样例:
12
题解
构造矩阵快速幂,挺烦的,全在草稿纸上了,只能提供代码了.
一维和二维的矩阵快速幂需要掌握
//矩阵快速幂
//求fn的前n项和Sn mod m
ll n,m;
const int N = 3;
ll a[N][N] = {
{0,1,0},
{1,1,1},
{0,0,1}
};
ll f1[N] = {1,1,1};
ll mul(ll c[N],ll a[N],ll b[N][N]){ //一维
ll tmp[N]={0};
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
tmp[i] = (tmp[i] + a[j]*b[j][i]) % m;
}
}
memcpy(c,tmp,sizeof(tmp));
}
ll mul(ll c[N][N],ll a[N][N],ll b[N][N]){ //二维
ll tmp[N][N] = {0};
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
for(int k=0;k<N;k++){
tmp[i][j] = (tmp[i][j] + a[i][k]*b[k][j]) % m;
}
}
}
memcpy(c,tmp,sizeof(tmp));
}
int main(){
scanf("%lld %lld",&n,&m); //n的
n--;
while(n){
if(n & 1)mul(f1,f1,a); //f1 = f1 * a;
mul(a,a,a); //a = a * a;
n >>= 1;
}
printf("%lld\n",f1[2]);
return 0;
}