AcWing 1303. 斐波那契前 n 项和 (矩阵乘法)

题意

大家都知道 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;
} 




你可能感兴趣的:(acwing,提高课题解)