POJ 3070 Fibonacci (矩阵快速幂)

本文介绍了如何使用快速幂算法高效地计算Fibonacci数列中任意项的最后四位数,并提供了实现代码。适用于对算法优化和数列计算感兴趣的读者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Fibonacci

Time Limit: 1000MS 

Memory Limit: 65536K

Total Submissions: 6850  Accepted: 4855

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

思路:快速幂利用的是二进制的思想,比如5^7,其中7在二进制中表示为111,则5^7 = 5*1 + 5*5*1 + 5*5*5*5*1,再比如5^5,5的二进制是101,则5^5 = 5*1 + 5*5*0 + 5*5*5*5*1,其实就是把5以二进制的形式拆开了,拆成1和4。这是整数的快速幂求法。矩阵的快速幂也是如此,只要把定义矩阵相乘定义下来,做法是一样的。

View Code
 1 #include <set>
 2 #include <map>
 3 #include <stack>
 4 #include <queue>
 5 #include <vector>
 6 #include <cmath>
 7 #include <cstdio>
 8 #include <cstring>
 9 #include <iostream>
10 #include <string>
11 #include <algorithm>
12 //#define SIZE
13 //#define inf
14 #define mod 10000
15 
16 using namespace std;
17 
18 typedef __int64 Int;
19 typedef long long ll;
20 typedef unsigned long long ull;
21 
22 const double PI = acos(-1.0);
23 const double eps = 1e-8;
24 
25 struct node
26 {
27     Int f[3][3];
28 }first;
29 
30 Int N;
31 
32 node mul(node a,node b)  //矩阵乘法
33 {
34     node ret;
35     for(int i=1; i<=2; i++)
36         for(int j=1; j<=2; j++)
37             ret.f[i][j] = 0;
38     for(int i=1; i<=2; i++)
39     {
40         for(int j=1; j<=2; j++)
41         {
42             for(int k=1; k<=2; k++)
43             {
44                 ret.f[i][j] += (a.f[i][k] * b.f[k][j]) % mod;
45             }
46             ret.f[i][j] %= mod;
47         }
48     }
49     return ret;
50 }
51 
52 Int fp(Int n)  //快速幂取模
53 {
54     node ret;
55     ret.f[1][1] = ret.f[1][2] = ret.f[2][1] = 1;
56     ret.f[2][2] = 0;
57     first.f[1][1] = first.f[1][2] = first.f[2][1] = 1;
58     first.f[2][2] = 0;
59     while(n)
60     {
61         if(n & 1)
62             ret = mul(ret,first);
63         n >>= 1;
64         first = mul(first,first);
65     }
66     return ret.f[1][1];
67 }
68 
69 int main()
70 {
71     while(~scanf("%I64d",&N) && N != -1)
72     {
73         if(N <= 1)
74             printf("%I64d\n",N);
75         else
76         {
77             Int ans = fp(N-2);
78             printf("%I64d\n",ans);
79         }
80     }
81     return 0;
82 }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值