这题并不复杂。

设$A=\begin{pmatrix} 1 & 1 \\ 1 & 0 \end{pmatrix}$

由题中公式:

$\begin{pmatrix}
f(n+1) & f(n)\\ 
f(n+1) & f(n-1)
\end{pmatrix} = {\begin{pmatrix}
1 & 1 \\ 
1 & 0
\end{pmatrix}}^{n}$

可知,若要求f(n)只要求矩阵A的n次方即可。设我们所需的矩阵为$Answer$.

对于此题,我们可以先将$Answer$矩阵设置为$E$。

再求出${A}^{{2}^{0}}$、${A}^{{2}^{1}}$、${A}^{{2}^{2}}$ ... ${A}^{{2}^{m}}$ (${2}^{m}\leq n <{2}^{m+1}$)

其中,后一个矩阵为前一个矩阵的平方。

把他们储存起来。

对上述矩阵从后到前遍历。

当遍历到第i项时,若${2}^{i} \leq n$,则将$Answer$矩阵与此矩阵项相乘,积作为新的$Answer$矩阵。然后,将$n$减去${2}^{i}$,再接着遍历下一项,直至$n = 0$。

遍历结束后的$Answer$矩阵即为我们所需的矩阵。

 1 #include <cstddef>
2 #include <cstdio>
3 #include <cstring>
4
5 struct matrix {
6 unsigned m[2][2];
7 };
8
9 #define multiply(a,b,r) (((r)[0][0]=(a)[0][0]*(b)[0][0]+(a)[0][1]*(b)[1][0]),((r)[0][1]=(a)[0][0]*(b)[0][1]+(a)[0][1]*(b)[1][1]),((r)[1][0]=(a)[1][0]*(b)[0][0]+(a)[1][1]*(b)[1][0]),((r)[1][1]=(a)[1][0]*(b)[0][1]+(a)[1][1]*(b)[1][1]))
10
11 int fibo_mod_by_10000(unsigned int n) {
12 if (n == 0)
13 return 0;
14 unsigned int mask = 0u, m = 0u;
15
16 while ((mask & n) != n) {
17 mask <<= 1u;
18 mask += 1u;
19 ++m;
20 }
21
22 matrix * ms = new matrix[m + 1u];
23 ms[1u].m[0][0] = 1u;
24 ms[1u].m[0][1] = 1u;
25 ms[1u].m[1][0] = 1u;
26 ms[1u].m[1][1] = 0u;
27
28 for (unsigned int i = 1u; i < m; ++i) {
29 multiply(ms[i].m, ms[i].m, ms[i + 1].m);
30 ms[i + 1].m[0][0] %= 10000u;
31 ms[i + 1].m[0][1] %= 10000u;
32 ms[i + 1].m[1][0] %= 10000u;
33 ms[i + 1].m[1][1] %= 10000u;
34 }
35
36 matrix result, tmp;
37 memcpy(&result, &(ms[m]), sizeof(matrix));
38 n -= (1u << (m - 1u));
39
40 while (n != 1u && n != 0u) {
41 while ((1u << (m - 1u)) > n)
42 --m;
43 memcpy(&tmp, &result, sizeof(matrix));
44 multiply(tmp.m, ms[m].m, result.m);
45 result.m[0][0] %= 10000u;
46 result.m[0][1] %= 10000u;
47 result.m[1][0] %= 10000u;
48 result.m[1][1] %= 10000u;
49 n -= (1u << (m - 1u));
50 }
51 unsigned r;
52 delete[] ms;
53 if (n == 1u)
54 return result.m[0][0];
55 else
56 return result.m[0][1];
57 }
58
59 int main()
60 {
61 int i;
62 while ((scanf("%d", &i)), (i != -1))
63 printf("%d\n", fibo_mod_by_10000(i));
64 return 0;
65 }

POJ 3070 - 快速矩阵幂求斐波纳契数列的更多相关文章

  1. 【poj3070】矩阵乘法求斐波那契数列

    [题目描述] 我们知道斐波那契数列0 1 1 2 3 5 8 13…… 数列中的第i位为第i-1位和第i-2位的和(规定第0位为0,第一位为1). 求斐波那契数列中的第n位mod 10000的值. [ ...

  2. poj3070矩阵快速幂求斐波那契数列

      Fibonacci Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13172   Accepted: 9368 Desc ...

  3. 51 Nod 1242 矩阵快速幂求斐波那契数列

    #include<bits/stdc++.h> #define mod 1000000009 using namespace std; typedef long long ll; type ...

  4. python 快速幂求斐波那契数列

    先占坑 后面再写详细的 import numpy as np def pow(n): a = np.array([[1,0],[0,1]]) b = np.array([[1,1],[1,0]]) n ...

  5. codeforce 227E 矩阵快速幂求斐波那契+N个连续数求最大公约数+斐波那契数列的性质

    E. Anniversary time limit per test2 seconds memory limit per test256 megabytes inputstandard input o ...

  6. Java算法求最大最小值,冒泡排序,斐波纳契数列一些经典算法<不断更新中>

    清明在家,无聊,把一些经典的算法总结了一下. 一.求最大,最小值 Scanner input=new Scanner(System.in); int[] a={21,31,4,2,766,345,2, ...

  7. C# 求斐波那契数列的前10个数字 :1 1 2 3 5 8 13 21 34 55

    //C# 求斐波那契数列的前10个数字 :1 1 2 3 5 8 13 21 34 55 using System; using System.Collections.Generic; using S ...

  8. 黑马入学基础测试(三)求斐波那契数列第n项,n<30,斐波那契数列前10项为 1,1,2,3,5,8,13,21,34,55

    .获得用户的输入 计算      3打印就行了.   这里用到了java.util.Scanner   具体API  我就觉得不常用.解决问题就ok了.注意的是:他们按照流体的方式读取.而不是刻意反复 ...

  9. golang 闭包求斐波那契数列

    题目是Go指南中的闭包求斐波那契数列 package main import "fmt" // 返回一个"返回int的函数" func fibonacci() ...

随机推荐

  1. 1010 过河卒 2002年NOIP全国联赛普及组codevs

    1010 过河卒  2002年NOIP全国联赛普及组codevs 题目描述 Description 如图,A 点有一个过河卒,需要走到目标 B 点.卒行走规则:可以向下.或者向右.同时在棋盘上的任一点 ...

  2. - > 贪心基础入门讲解二——活动安排问题

    有若干个活动,第i个开始时间和结束时间是[Si,fi),只有一个教室,活动之间不能交叠,求最多安排多少个活动? 分析: 我们就是想提高教室地利用率,尽可能多地安排活动.考虑容易想到的几种贪心策略: ( ...

  3. 24、Java并发性和多线程-信号量

    以下内容转自http://ifeve.com/semaphore/: Semaphore(信号量) 是一个线程同步结构,用于在线程间传递信号,以避免出现信号丢失(译者注:下文会具体介绍),或者像锁一样 ...

  4. 项目中应用到的框架和技术之二——ol3-ext

    ol3-ext有很多很丰富的效果,可以不用重复造轮子,ol3-ext示例大全:http://viglino.github.io/ol3-ext/ 在本次项目中使用到了ol3-ext的两个功能:图层管理 ...

  5. spring mvc参数校验

    一.在SringMVC中使用 使用注解 1.准备校验时使用的JAR validation-api-1.0.0.GA.jar:JDK的接口: hibernate-validator-4.2.0.Fina ...

  6. 条款31: 千万不要返回局部对象的引用,也不要返回函数内部用new初始化的指针的引用

    先看第一种情况:返回一个局部对象的引用.它的问题在于,局部对象 ----- 顾名思义 ---- 仅仅是局部的.也就是说,局部对象是在被定义时创建,在离开生命空间时被销毁的.所谓生命空间,是指它们所在的 ...

  7. 网络请求之GET、POST请求

    网络请求-GET请求: 1,NSURL: 请求地址. 2,NSURLRequest :一个NSURLRequest对象就代表一个请求.它包括的信息有: 1)一个NSURL对象 GET请求,不须要写请求 ...

  8. PAT Broken Keyboard (20)

    题目描写叙述 On a broken keyboard, some of the keys are worn out. So when you type some sentences, the cha ...

  9. 深入学习理解java-ThreadLocal

    导读 首先,ThreadLocal 不是用来解决共享对象的多线程訪问问题的,普通情况下,通过ThreadLocal.set() 到线程中的对象是该线程自己使用的对象,其它线程是不须要訪问的,也訪问不到 ...

  10. php訪问控制

    訪问控制通过keywordpublic,protected和private来实现. 被定义为公有的类成员能够在不论什么地方被訪问.被定义为受保护的类成员则能够被其自身以及其子类和父类訪问.被定义为私有 ...