POJ3070 Fibonacci

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

 
 
正解:矩阵乘法+矩阵快速幂
解题报告:
  就是一个斐波那契数列求第几项是多少的题,考虑用矩阵乘法优化递推公式,显然要用矩阵快速幂(尽管矩阵不满足交换律但是满足结合律)。
  因为只有2X2,直接打不用for也可以。
 
 1 //It is made by jump~
 2 #include <iostream>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <cstdio>
 6 #include <cmath>
 7 #include <algorithm>
 8 #include <ctime>
 9 #include <vector>
10 #include <queue>
11 #include <map>
12 #include <set>
13 #ifdef WIN32   
14 #define OT "%I64d"
15 #else
16 #define OT "%lld"
17 #endif
18 using namespace std;
19 typedef long long LL;
20 const int MOD = 10000;
21 int n;
22 
23 struct Fibn{
24     LL s[5];
25 }a,b;
26 
27 inline int getint()
28 {
29        int w=0,q=0;
30        char c=getchar();
31        while((c<'0' || c>'9') && c!='-') c=getchar();
32        if (c=='-')  q=1, c=getchar();
33        while (c>='0' && c<='9') w=w*10+c-'0', c=getchar();
34        return q ? -w : w;
35 }
36 
37 inline Fibn cheng(Fibn p,Fibn q){
38     Fibn tmp;
39     tmp.s[1]=p.s[1]*q.s[1]+p.s[2]*q.s[3]; tmp.s[1]%=MOD;
40     tmp.s[2]=p.s[1]*q.s[2]+p.s[2]*q.s[4]; tmp.s[2]%=MOD;    
41     tmp.s[3]=p.s[3]*q.s[1]+p.s[4]*q.s[3]; tmp.s[3]%=MOD;
42     tmp.s[4]=p.s[3]*q.s[2]+p.s[4]*q.s[4]; tmp.s[4]%=MOD;
43     return tmp;
44 }
45 
46 inline void fib(){
47     a.s[1]=1; a.s[2]=0; a.s[3]=0; a.s[4]=1;
48     b.s[1]=0; b.s[2]=1; b.s[3]=1; b.s[4]=1;
49     while(n) {
50     if(n&1) a=cheng(a,b);
51     b=cheng(b,b);
52     n=n/2;
53     }
54     //printf("%d %d %d %d\n",a.s[1],a.s[2],a.s[3],a.s[4]);
55     printf("%d\n",(int)a.s[3]);
56 }
57 
58 inline void work(){
59     while(1) {
60     n=getint();
61     if(n==-1) break;
62     if(n==0) { printf("0\n"); continue; }
63     fib();
64     }
65 }
66 
67 int main()
68 {
69   work();
70   return 0;
71 }

 

转载于:https://www.cnblogs.com/ljh2000-jump/p/5695317.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值