hpuvj【3070】Fibonacci(矩阵快速幂求模)

本文介绍了一种利用矩阵快速幂算法高效计算斐波那契数列第n项最后四位数字的方法。通过定义特定的2x2矩阵并利用矩阵乘法及快速幂运算,文章提供了一个C++实现示例。



Time Limit: 1000MS Memory Limit: 65536KB 64bit IO Format: %I64d & %I64u

 Status

Description

In the Fibonacci integer sequence, F0 = 0, F1 = 1, and Fn = Fn − 1 + Fn − 2 for n ≥ 2. For example, the first ten terms of the Fibonacci sequence are:

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, …

An alternative formula for the Fibonacci sequence is

.

Given an integer n, your goal is to compute the last 4 digits of Fn.

Input

The input test file will contain multiple test cases. Each test case consists of a single line containing n (where 0 ≤ n ≤ 1,000,000,000). The end-of-file is denoted by a single line containing the number −1.

Output

For each test case, print the last four digits of Fn. If the last four digits of Fn are all zeros, print ‘0’; otherwise, omit any leading zeros (i.e., print Fn mod 10000).

Sample Input

0
9
999999999
1000000000
-1

Sample Output

0
34
626
6875

Hint

As a reminder, matrix multiplication is associative, and the product of two 2 × 2 matrices is given by

.

Also, note that raising any 2 × 2 matrix to the 0th power gives the identity matrix:

.

Source


一道涉及到矩阵快速幂的知识的题 本来快速幂没学好 今天还专门说这个了,所以 看了半天才略懂了 一些,代码如下:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct Mat//定义矩阵
{
	int a[2][2];
	void init()
	{
		memset(a,0,sizeof(a));
		a[0][0]=a[1][1]=1;
	 } 
};
Mat mul(Mat a,Mat b)//矩阵乘法 
{
	Mat ans;
	ans.init();
	for(int i=0;i<2;i++)
	{
		for(int j=0;j<2;j++)
		{
			ans.a[i][j]=0;
			for(int k=0;k<2;k++)
            {
                ans.a[i][j]+=a.a[i][k]*b.a[k][j];
            }
            ans.a[i][j]%=10000;
		}
	}
	return ans;
}
Mat power(Mat a,int num)//矩阵快速幂模板 
{
	Mat ans;
	ans.init();
	while(num)
	{
		if(num%2==1)
		{
			ans=mul(ans,a);
		}
		num/=2;
		a=mul(a,a);
	}
	return ans;
}
int main()
{
	int n;
	while(scanf("%d",&n)!=EOF&&n!=-1)
	{
		if(n==0)
		{
			printf("0\n");
			continue;
		}
		Mat a,ans;
		a.a[0][1]=a.a[0][0]=a.a[1][0]=1;
		a.a[1][1]=0;
		ans=power(a,n);
		printf("%d\n",ans.a[0][1]%10000);
	}
	return 0;
}


Time Limit: 1000MS Memory Limit: 65536KB 64bit IO Format: %I64d & %I64u

 Status

Description

In the Fibonacci integer sequence, F0 = 0, F1 = 1, and Fn = Fn − 1 + Fn − 2 for n ≥ 2. For example, the first ten terms of the Fibonacci sequence are:

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, …

An alternative formula for the Fibonacci sequence is

.

Given an integer n, your goal is to compute the last 4 digits of Fn.

Input

The input test file will contain multiple test cases. Each test case consists of a single line containing n (where 0 ≤ n ≤ 1,000,000,000). The end-of-file is denoted by a single line containing the number −1.

Output

For each test case, print the last four digits of Fn. If the last four digits of Fn are all zeros, print ‘0’; otherwise, omit any leading zeros (i.e., print Fn mod 10000).

Sample Input

0
9
999999999
1000000000
-1

Sample Output

0
34
626
6875

Hint

As a reminder, matrix multiplication is associative, and the product of two 2 × 2 matrices is given by

.

Also, note that raising any 2 × 2 matrix to the 0th power gives the identity matrix:

.

Source

### 矩阵快速幂计算斐波那契数列 矩阵快速幂是一种高效的算法,用于通过矩阵运算加速递推关系式的计算。对于斐波那契数列 \( F_n \),其定义如下: \[ F_0 = 0,\quad F_1 = 1,\quad F_{n} = F_{n-1} + F_{n-2}\ (n \geq 2) \] 利用矩阵形式表示上述递推关系,可以写成: \[ \begin{bmatrix} F_{n+1}\\ F_{n} \end{bmatrix} = \begin{bmatrix} 1 & 1\\ 1 & 0 \end{bmatrix} \times \begin{bmatrix} F_{n}\\ F_{n-1} \end{bmatrix} \] 因此,可以通过不断右乘该矩阵的方式,将问题转化为矩阵的幂次运算。 以下是基于 Java 的实现代码,采用迭代方式而非递归,从而避免堆栈溢出并提高效率[^2]。 #### 实现代码 ```java public class FibonacciMatrixPower { // 定义矩阵类 static class Matrix { long[][] data; public Matrix(long a, long b, long c, long d) { this.data = new long[][]{{a, b}, {c, d}}; } // 矩阵相乘函数 public static Matrix multiply(Matrix m1, Matrix m2) { long a11 = m1.data[0][0], a12 = m1.data[0][1]; long a21 = m1.data[1][0], a22 = m1.data[1][1]; long b11 = m2.data[0][0], b12 = m2.data[0][1]; long b21 = m2.data[1][0], b22 = m2.data[1][1]; return new Matrix( a11 * b11 + a12 * b21, a11 * b12 + a12 * b22, a21 * b11 + a22 * b21, a21 * b12 + a22 * b22 ); } } // 计算矩阵的 n 次幂 public static Matrix matrixPow(Matrix base, long exp) { Matrix result = new Matrix(1, 0, 0, 1); // 单位矩阵 while (exp > 0) { if ((exp & 1) != 0) { result = Matrix.multiply(result, base); } base = Matrix.multiply(base, base); exp >>= 1; } return result; } // 使用矩阵快速幂计算斐波那契数列第 n 项 public static long fibonacci(long n) { if (n == 0) return 0; if (n == 1) return 1; Matrix T = new Matrix(1, 1, 1, 0); // 转移矩阵 Matrix res = matrixPow(T, n - 1); return res.data[0][0]; // 返回结果 } public static void main(String[] args) { int n = 1_000_000; // 输入较大的 n 值测试性能 System.out.println("Fibonacci(" + n + ") = " + fibonacci(n)); } } ``` --- ### 关键点解析 1. **矩阵初始化** 初始转移矩阵为: \[ T = \begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix} \] 这一矩阵满足斐波那契数列的递推性质[^1]。 2. **单位矩阵的作用** 在矩阵快速幂中,初始结果设为单位矩阵: \[ I = \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix} \] 类似于数值中的 `1`,作为乘法的起点。 3. **时间复杂度优化** 相较于传统递归方法的时间复杂度 \( O(2^n) \)矩阵快速幂的时间复杂度降为 \( O(\log n) \),极大地提升了计算效率。 4. **边界条件处理** 对于特殊情况如 \( n = 0 \) 或 \( n = 1 \),直接返回对应的结果以减少不必要的计算开销。 --- ### 性能表现 当 \( n = 1,000,000 \) 时,此方法能够在极短时间内完成计算而不会引发堆栈溢出或显著延迟[^3]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值