斐波那契前 n 项和 - 矩阵乘法快速幂

1303. 斐波那契前 n 项和 - AcWing题库

斐波那契前 n 项和 - 矩阵乘法快速幂_第1张图片

F_{i}=[f_{i},f_{i+1},S_{i}]

F_{i+1}=[f_{i+1},f_{i+2},S_{i+1}]

构造矩阵A使F_{i}*A=F_{i + 1}

                              0        1        0

 A        =          [      1        1        1        ]

                              0        0        1

F_{n}=F_{1}*A^{n-1}

然后对这个式子进行快速幂,挺神奇的

#include
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define endl '\n'
 
using namespace std;
 
typedef pair PII;
typedef long long ll;
typedef long double ld;

const int N = 3;

int n, mod;

void mul(int C[], int A[], int B[][N])
{
	int tmp[N] = {0};
	
	for(int i = 0; i < N; i ++)
		for(int j = 0; j < N; j ++)
			tmp[i] = (tmp[i] + (ll)A[j] * B[j][i]) % mod;
			
	memcpy(C, tmp, sizeof tmp);
}

void mul(int C[][N], int A[][N], int B[][N])
{
	int 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] + (ll)A[i][k] * B[k][j]) % mod;
				
	memcpy(C, tmp, sizeof tmp);
}

int main()
{
	IOS
	int f1[N] = {1, 1, 1};
	int A[N][N] = {{0, 1, 0}, {1, 1, 1}, {0, 0, 1}};
	
	cin >> n >> mod;
	int k = n - 1;
	while(k)
	{
		if(k & 1)mul(f1, f1, A);//f1 = f1 * A 
		mul(A, A, A);//A = A * A
		k >>= 1;
	}
	
	cout << f1[2];
	
	
	return 0;
} 

你可能感兴趣的:(数论,模板,矩阵,算法,线性代数)