[2016-02-04][POJ][3070][Fibonacci]

[2016-02-04][POJ][3070][Fibonacci]

POJ - 3070

Fibonacci

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

Submit 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:

.

  • 时间:2016-02-04 23:19:26 星期四
  • 题目编号:POJ 3070
  • 题目大意:求斐波那契数
  • 方法:矩阵快速幂

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

#include <vector>

#include <list>

#include <map>

#include <set>

#include <deque>

#include <queue>

#include <stack>

#include <bitset>

#include <algorithm>

#include <functional>

#include <numeric>

#include <utility>

#include <sstream>

#include <iostream>

#include <iomanip>

#include <cstdio>

#include <cmath>

#include <cstdlib>

#include <cctype>

#include <string>

#include <cstring>

#include <cstdio>

#include <cmath>

#include <cstdlib>

#include <ctime>

using namespace std;

typedef long long LL;

#define CLR(x,y) memset((x),(y),sizeof((x)))

#define getint(x) int (x);scanf("%d",&(x))

#define get2int(x,y) int (x),(y);scanf("%d%d",&(x),&(y))

#define get3int(x,y,z) int (x),(y),(z);scanf("%d%d%d",&(x),&(y),&(z))

#define getll(x) LL (x);scanf("%I64d",&(x))

#define get2ll(x,y) LL (x),(y);scanf("%I64d%I64d",&(x),&(y))

#define get3ll(x,y,z) LL (x),(y),(z);scanf("%I64d%I64d%I64d",&(x),&(y),&(z))

#define getdb(x) double (x);scanf("%lf",&(x))

#define get2db(x,y) double (x),(y);scanf("%lf%lf",&(x),&(y))

#define get3db(x,y,z) double (x),(y),(z);scanf("%lf%lf%lf",&(x),&(y),&(z))

#define getint2(x) scanf("%d",&(x))

#define get2int2(x,y) scanf("%d%d",&(x),&(y))

#define get3int2(x,y,z) scanf("%d%d%d",&(x),&(y),&(z))

#define getll2(x) scanf("%I64d",&(x))

#define get2ll2(x,y) scanf("%I64d%I64d",&(x),&(y))

#define get3ll2(x,y,z) scanf("%I64d%I64d%I64d",&(x),&(y),&(z))

#define getdb2(x) scanf("%lf",&(x))

#define get2db2(x,y) scanf("%lf%lf",&(x),&(y))

#define get3db2(x,y,z) scanf("%lf%lf%lf",&(x),&(y),&(z))

#define getstr(str) scanf("%s",str)

#define get2str(str1,str2) scanf("%s%s",str1,str2)

#define FOR(x,y,z) for(int (x)=(y);(x)<(z);(x)++)

#define FORD(x,y,z) for(int (x)=(y);(x)>=(z);(x)--)

#define FOR2(x,y,z) for((x)=(y);(x)<(z);(x)++)

#define FORD2(x,y,z) for((x)=(y);(x)>=(z);(x)--)

const int maxn = 1000 + 100;

#define MOD 10000

const int mat_size = 2;

struct matrix{

        long long a[mat_size][mat_size];

};

matrix matrixE;//单位矩阵

void inimatrixE(){

        for(int i = 0;i < mat_size;++i)

                for(int j = 0;j < mat_size;++j)

                        matrixE.a[i][j] = i == j ? 1 : 0;

}

void mat_mult(matrix & a,matrix & b,matrix & c,int m,int n,int s,long long mod){

        //a == m*n      b == n*s        c == m*s

        memset(c.a,0,sizeof(c.a));

        for(int i = 0 ;i < m ; ++i)

                for(int k = 0;k < n ; ++k)

                        for(int j = 0 ; j < s ; ++j){

                                c.a[i][j] = (c.a[i][j] + a.a[i][k]*b.a[k][j]) % mod;

//如果结果不会超过longlong范围,那么取模运算可以放在第二个for内(第3个for 外面)

                        }

}

void quick_matrix_pow(matrix & a,int p,matrix & res){

        memset(res.a,0,sizeof(res.a));

        matrix tmp = a,tmpres;

        res = matrixE;

        while(p >= 1){

                if(p & 1){

                        mat_mult(tmp,res,tmpres,mat_size,mat_size,mat_size,MOD);

                        res = tmpres;

                }

                p >>= 1;

                mat_mult(tmp,tmp,tmpres,mat_size,mat_size,mat_size,MOD);

                tmp = tmpres;

        }

}

int main()

{

        int n;

        inimatrixE();

    while(~scanf("%d",&n) && ~n)

    {

        matrix P = {1,1,1,0},res;

        quick_matrix_pow(P,n,res);

        printf("%lld\n",res.a[0][1]);

    }

    return 0;

}

来自为知笔记(Wiz)

时间: 2024-12-12 17:31:14

[2016-02-04][POJ][3070][Fibonacci]的相关文章

poj 3070 Fibonacci

http://poj.org/problem?id=3070 矩阵的快速幂,二分 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define maxn 10000 5 using namespace std; 6 const int mod=10000; 7 8 int n; 9 struct node 10 { 11 int a[4][4]; 12 }; 13 14 node mu

poj 3070 Fibonacci (矩阵快速幂求斐波那契数列的第n项)

题意就是用矩阵乘法来求斐波那契数列的第n项的后四位数.如果后四位全为0,则输出0,否则 输出后四位去掉前导0,也...就...是...说...输出Fn%10000. 题目说的如此清楚..我居然还在%和/来找后四位还判断是不是全为0还输出时判断是否为0然后 去掉前导0.o(╯□╰)o 还有矩阵快速幂的幂是0时要特判. P.S:今天下午就想好今天学一下矩阵乘法方面的知识,这题是我的第一道正式接触矩阵乘法的题,欧耶! #include<cstdio> #include<iostream>

矩阵快速幂 POJ 3070 Fibonacci

题目传送门 1 /* 2 矩阵快速幂:求第n项的Fibonacci数,转置矩阵都给出,套个模板就可以了.效率很高啊 3 */ 4 #include <cstdio> 5 #include <algorithm> 6 #include <cstring> 7 #include <cmath> 8 using namespace std; 9 10 const int MAXN = 1e3 + 10; 11 const int INF = 0x3f3f3f3f;

POJ 3070 Fibonacci 矩阵快速求法

就是Fibonacci的矩阵算法,不过增加一点就是因为数字很大,所以需要取10000模,计算矩阵的时候取模就可以了. 本题数据不强,不过数值本来就限制整数,故此可以0ms秒了. 下面程序十分清晰了,因为分开了几个小函数了,适合初学者参考下. #include <stdio.h> const int MOD = 10000; void mulOneMatrix(int F[2][2]) { int a = F[0][0]; int b = F[1][0]; F[0][0] = (a+b)%MOD

POJ 3070 Fibonacci(矩阵快速幂)

题目链接 题意 : 用矩阵相乘求斐波那契数的后四位. 思路 :基本上纯矩阵快速幂. 1 //3070 2 #include <iostream> 3 #include <cstring> 4 #include <cstdio> 5 6 using namespace std; 7 8 struct Matrix 9 { 10 int v[2][2]; 11 }; 12 int n; 13 14 Matrix matrix_mul(Matrix a,Matrix b) 1

POJ 3070 Fibonacci(矩阵高速功率)

职务地址:POJ 3070 用这个题学会了用矩阵高速幂来高速求斐波那契数. 依据上个公式可知,第1行第2列和第2行第1列的数都是第n个斐波那契数.所以构造矩阵.求高速幂就可以. 代码例如以下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #include

poj 3070 Fibonacci 矩阵快速幂

题目链接:http://poj.org/problem?id=3070 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 t

矩阵经典题目六:poj 3070 Fibonacci

http://poj.org/problem?id=3070 按已构造好的矩阵,那么该矩阵的n次方的右上角的数便是f[n]. #include <stdio.h> #include <iostream> #include <map> #include <set> #include <list> #include <stack> #include <vector> #include <math.h> #inclu

poj 3070 Fibonacci(矩阵快速幂求Fibonacci数列)

题目链接: http://poj.org/problem?id=3070 题意: 我们知道斐波那契数列0 1 1 2 3 5 8 13-- 数列中的第i位为第i-1位和第i-2位的和(规定第0位为0,第一位为1). 求斐波那契数列中的第n位mod 10000的值. 思路: 这里的n很大,有10^9,for一遍肯定是不可以的. 所以要用矩阵乘法求斐波那契数列. f[n+1] = f[n]+f[n-1] f[n] = f[n] 构造以下矩阵,n次幂,mat[1][0] 就是答案 1 1 1 0 求矩