POJ 3070 - 快速矩阵幂求斐波纳契数列
这题并不复杂。
设$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 - 快速矩阵幂求斐波纳契数列的更多相关文章
- 【poj3070】矩阵乘法求斐波那契数列
[题目描述] 我们知道斐波那契数列0 1 1 2 3 5 8 13…… 数列中的第i位为第i-1位和第i-2位的和(规定第0位为0,第一位为1). 求斐波那契数列中的第n位mod 10000的值. [ ...
- poj3070矩阵快速幂求斐波那契数列
Fibonacci Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 13172 Accepted: 9368 Desc ...
- 51 Nod 1242 矩阵快速幂求斐波那契数列
#include<bits/stdc++.h> #define mod 1000000009 using namespace std; typedef long long ll; type ...
- python 快速幂求斐波那契数列
先占坑 后面再写详细的 import numpy as np def pow(n): a = np.array([[1,0],[0,1]]) b = np.array([[1,1],[1,0]]) n ...
- codeforce 227E 矩阵快速幂求斐波那契+N个连续数求最大公约数+斐波那契数列的性质
E. Anniversary time limit per test2 seconds memory limit per test256 megabytes inputstandard input o ...
- Java算法求最大最小值,冒泡排序,斐波纳契数列一些经典算法<不断更新中>
清明在家,无聊,把一些经典的算法总结了一下. 一.求最大,最小值 Scanner input=new Scanner(System.in); int[] a={21,31,4,2,766,345,2, ...
- 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 ...
- 黑马入学基础测试(三)求斐波那契数列第n项,n<30,斐波那契数列前10项为 1,1,2,3,5,8,13,21,34,55
.获得用户的输入 计算 3打印就行了. 这里用到了java.util.Scanner 具体API 我就觉得不常用.解决问题就ok了.注意的是:他们按照流体的方式读取.而不是刻意反复 ...
- golang 闭包求斐波那契数列
题目是Go指南中的闭包求斐波那契数列 package main import "fmt" // 返回一个"返回int的函数" func fibonacci() ...
随机推荐
- 1010 过河卒 2002年NOIP全国联赛普及组codevs
1010 过河卒 2002年NOIP全国联赛普及组codevs 题目描述 Description 如图,A 点有一个过河卒,需要走到目标 B 点.卒行走规则:可以向下.或者向右.同时在棋盘上的任一点 ...
- - > 贪心基础入门讲解二——活动安排问题
有若干个活动,第i个开始时间和结束时间是[Si,fi),只有一个教室,活动之间不能交叠,求最多安排多少个活动? 分析: 我们就是想提高教室地利用率,尽可能多地安排活动.考虑容易想到的几种贪心策略: ( ...
- 24、Java并发性和多线程-信号量
以下内容转自http://ifeve.com/semaphore/: Semaphore(信号量) 是一个线程同步结构,用于在线程间传递信号,以避免出现信号丢失(译者注:下文会具体介绍),或者像锁一样 ...
- 项目中应用到的框架和技术之二——ol3-ext
ol3-ext有很多很丰富的效果,可以不用重复造轮子,ol3-ext示例大全:http://viglino.github.io/ol3-ext/ 在本次项目中使用到了ol3-ext的两个功能:图层管理 ...
- spring mvc参数校验
一.在SringMVC中使用 使用注解 1.准备校验时使用的JAR validation-api-1.0.0.GA.jar:JDK的接口: hibernate-validator-4.2.0.Fina ...
- 条款31: 千万不要返回局部对象的引用,也不要返回函数内部用new初始化的指针的引用
先看第一种情况:返回一个局部对象的引用.它的问题在于,局部对象 ----- 顾名思义 ---- 仅仅是局部的.也就是说,局部对象是在被定义时创建,在离开生命空间时被销毁的.所谓生命空间,是指它们所在的 ...
- 网络请求之GET、POST请求
网络请求-GET请求: 1,NSURL: 请求地址. 2,NSURLRequest :一个NSURLRequest对象就代表一个请求.它包括的信息有: 1)一个NSURL对象 GET请求,不须要写请求 ...
- PAT Broken Keyboard (20)
题目描写叙述 On a broken keyboard, some of the keys are worn out. So when you type some sentences, the cha ...
- 深入学习理解java-ThreadLocal
导读 首先,ThreadLocal 不是用来解决共享对象的多线程訪问问题的,普通情况下,通过ThreadLocal.set() 到线程中的对象是该线程自己使用的对象,其它线程是不须要訪问的,也訪问不到 ...
- php訪问控制
訪问控制通过keywordpublic,protected和private来实现. 被定义为公有的类成员能够在不论什么地方被訪问.被定义为受保护的类成员则能够被其自身以及其子类和父类訪问.被定义为私有 ...