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() ...
随机推荐
- F - Experienced Endeavour 矩阵快速幂
Alice is given a list of integers by Bob and is asked to generate a new list where each element in t ...
- jconsole远程连接 jmx配置注意事项
由于在测试程序时需要收集程序运行时的内存,CPU等消耗情况.选择了jconsole这个jdk自带工具来观察.为了不影响程序运行状态,用远程连接的方式来具体观察. 首先,程序是放在ubutun系统服务器 ...
- vue2的简单时间选择组件
github: https://github.com/longfei59418888/vui (记得给一个 start,以后有一起讨论,各种好组件) demo : http://60.205.2 ...
- Oracle Multitenant Environment (二) Purpose
Purpose of a Multitenant Environment A multitenant environment enables the central management of mul ...
- Centos7: 设置UTC时区
timedatectl set-timezone UTC
- shell中的四种模式匹配
POSIX为shell为进行模式匹配提供了四种参数替换结构(老版本的shell可能不支持),每种结构有两个参数:变量名(或变量号)及模式. 第一种模式: ${variable%pattern}, ...
- bootstrap-table方法之:expandRow-collapseRow,展开或关闭当前行数据
官方演示地址:http://issues.wenzhixin.net.cn/bootstrap-table/methods/expandRow-collapseRow.html <!DOCTYP ...
- 并发数 = QPS*平均响应时间
转:https://blog.csdn.net/luman1991/article/details/70919279 并发数 = QPS*平均响应时间 QPS(TPS):每秒钟request 每秒查询 ...
- ios7 真机调试 设置 bitcode
用Xcode 7 beta 3在真机(iOS 8.3)上运行一下工程,结果发现工程编译不过.看了下问题,报的是以下错误: ld: ‘/Users/**/Framework/SDKs/PolymerPa ...
- USRP通信的结构体和常量(上位机、下位机共用)
fw_common.h包括了USRP固件和上位机共用的代码,寄存器地址映射.结构体定义等 #include <stdint.h> /*! * Structs and constants f ...