Fibonacci 第 n 项

// Fibonacci 第 n 项.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

/*
https://loj.ac/p/10220

题目描述
大家都知道 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  mod m。

输入格式
输入 n,m。

输出格式
输出 f_n mod m。

样例
输入
5 1000
输出
5
数据范围与提示
对于 100\% 的数据, 1<= n <= 2* 10^9, 1<= m <= 10^9+10。
*/

#include <iostream>
#include <cstring>

using namespace std;

long long n, m;

long long A[2] = { 1,1 };
long long B[2][2] = {
	{0,1},
	{1,1},
};
long long R[2] = { 0,0 };


void mul(long long Z[2], long long X[2], long long Y[2][2]) {
	memset(Z, 0, sizeof(Z)*2);
	for (int i = 0; i < 2; i++) {
		for (int j = 0; j < 2; j++) {
			Z[i] += X[j] * Y[j][i];
			Z[i] %= m;
		}
	}
}

void mul(long long  ret[2][2], long long  X[2][2], long long  Y[2][2]) {
	memset(ret, 0, sizeof(ret[0][0]) * 2 * 2);
	for (int i = 0; i < 2; i++) {
		for (int j = 0; j < 2; j++) {
			for (int k = 0; k < 2; k++) {
				ret[i][j] += X[i][k] * Y[k][j];
				ret[i][j]   %= m;
			}
		}
	}
}


void mulrep(long long X[2][2], long long q) {
	long long tmp[2][2]; memset(tmp, 0, sizeof tmp);
	long long R[2][2]; memset(R, 0, sizeof R);
	for (int i = 0; i < 2; i++) { R[i][i] = 1; }
	long long RC[2][2]; memcpy(RC, R, sizeof RC);
	while (q != 0) {
		if (q & 1) {
			memcpy(RC, R, sizeof RC);
			mul(R, RC,X);
		}
		q >>= 1;
		mul(tmp,X,X);
		memcpy(X, tmp, sizeof tmp);
	}

	memcpy(X, R, sizeof R);
}


int main()
{	
	cin >> n;
	m = 1e9 + 7;
	mulrep(B, n -1);
	long long ret[2];
	mul(ret,A,B);
	
	cout << ret[0] <<  endl;
	
	return 0;
}

// 10220. 「一本通 6.5 例 2」Fibonacci 第 n 项.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//


/*
https://loj.ac/p/10220

题目描述
大家都知道 Fibonacci 数列吧,f_1=1,f_2=1,f_3=2,f_4=3,\dots,f_n=f_{n-1}+f_{n-2}。

现在问题很简单,输入 n 和 m,求 f_n\bmod m。

输入格式
输入 n,m。

输出格式
输出 f_n \bmod m。

5 1000

5

数据范围与提示
对于 100\% 的数据, 1<= n <= 2 X 10^9, 1<= m <= 10^9+10。
*/

#include <iostream>
#include <cstring>


using namespace std;

const int N = 3;
int n, m;


void mul(int res[][N], int a[][N], int b[][N]) {
	static int temp[N][N]; memset(temp, 0, sizeof temp);
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			for (int k = 0; k < N; k++) {
				temp[i][j] = temp[i][j] + 1LL*a[i][k] * b[k][j] % m;
				temp[i][j] %= m;
			}
		}
	}

	memcpy(res, temp, sizeof temp);
}


int main()
{
	cin >> n >> m;
	int f[N][N] = { 1,1,2 };
	n--;
	int a[N][N] = {
		{0,1,0},
		{1,1,1},
		{0,0,1}
	};

	while (n) {
		if (n & 1) mul(f, f, a);
		mul(a, a, a);
		n >>= 1;
	}

	cout << f[0][0] << endl;

	return 0;
}

posted on 2024-08-30 15:42  itdef  阅读(14)  评论(0)    收藏  举报

导航