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() ...
随机推荐
- 好不容易帮同事写的一个awk,要记下来
给昌哥写的过滤的东东. 是实现了,但感觉丑,不规范. 记得下先. 原始数据格式: -- :: [ pool--thread-: ] - [ DEBUG ] origin match ::, user: ...
- sqlalchemy foreign key查询和backref
首先在mysql中创建两个表如下: mysql) , primary key(id)); Query OK, rows affected (0.01 sec) mysql),user_id int, ...
- Centos7 上安装mysql遇上的问题:mysql无法正常启动
第一次在Centos上安装mysql遇到的一些问题. 第一步就遇到问题,安装mysql-server报错没有可用包. [解决方法] 先要安装mysql # wget http://repo.mysq ...
- Node & Express: some tips
1. 设置Express端口号: 在app.js中添加 app.set('port', process.env.PORT || 3000); 之后命令行中打入 PORT=1234 node app.j ...
- 二维数组的查找,刷题成功——剑指Offer
今天又做了一道题目,通过啦,欧耶! https://www.nowcoder.net/practice/abc3fe2ce8e146608e868a70efebf62e?tpId=13&tqI ...
- [JavaEE] Create API documents with Swagger
We mainly need to modify our Model and REST endpoint code to enable swagger Document. model/Book.jav ...
- 假设写一段代码引导PC开机这段代码是 ? Here is a tiny "OS" :-D
Hello world -- OS 我找到了华科绍志远博士的相关代码,发现他依据MIT的JOS的boot.S 稍作改动.然后单独剥离出来,能够非常好玩~ 资料下载地址: http://download ...
- WebView与JavaScript交互--Android
转载请注明出处: http://blog.csdn.net/forwardyzk/article/details/46819925 在工作中,有一个这种需求,须要用到WebView与javascri ...
- GitHub 高速上手 ---- 创建密钥,连接
首先要在GitHub上创建一个帐号,因为本地Git仓库和GitHub仓库之间的传输是通过SSH加密的,所以要在本地生成一个私钥和一个密钥 命令,后面跟的邮箱.要跟你自己的:增加输出的位置:能够不用设置 ...
- 【数学】mex是什么
最近在看博弈论,SG函数,所以什么是mex呢 然后百度了一下得到: mex(S) 的值为集合 S 中没有出现过的最小自然数.例如,mex({1,2}) = 0.mex({0,1,2,3}) = 4