(矩阵快速幂)解所有类似Fibonacci 的题目

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

这个题是出题人好心,直接把规律给我们找出来了,那我们就只需要求那个矩阵的n次方,然后输出a[0][1]即可

1.先说说矩阵快速幂
为了类比快速幂,我们先写出快速幂的代码
快速幂求x的y次方,是把y看作二进制来的,矩阵快速幂也一样。
区别:
1.矩阵快速幂底数是矩阵,ren是矩阵
2.最终矩阵乘矩阵还是矩阵,也就是说函数返回矩阵,ans是矩阵
3.我们存答案的ans初始化应该是初等矩阵
所以涉及到矩阵的代码我们都要改

int pow_1(int x,int y){//x的y次方 int ren=x;int ans=1;while(y){if(y&1) ans*=ren;//取当前最末位的y,如果是1就继续乘ren ren*=ren;//下一位ren是当前ren的平方 1 2 4 8,这里8是x^4的平方,不是4的平方 y=y>>1;//y前进一位 }return ans;
} 

改完之后就是这样了

struct matrix
{LL x[2][2];
};
matrix mutimatrix(matrix a,matrix b)
{matrix temp; memset(temp.x,0,sizeof(temp.x));    for(int i=0;i<2;i++)for(int j=0;j<2;j++)for(int k=0;k<2;k++){temp.x[i][j]+=a.x[i][k]*b.x[k][j];temp.x[i][j]%=mod;}return temp;
}matrix k_powmatrix(matrix a,LL n)
{matrix temp;memset(temp.x,0,sizeof(temp.x));for(int i=0;i<2;i++)temp.x[i][i]=1;while(n){if(n&1)temp=mutimatrix(temp,a);a=mutimatrix(a,a);n>>=1;}return temp;
} 

这个出题人直接把意思说的明明白白的,直接求那个矩阵的n次方就ok

#include <iostream> 
#include <cstring>
#include <cstdio>
using namespace std; 
#define LL long long 
const int mod=10000; 
struct matrix
{LL x[2][2];
};
matrix mutimatrix(matrix a,matrix b)
{matrix temp; memset(temp.x,0,sizeof(temp.x));    for(int i=0;i<2;i++)for(int j=0;j<2;j++)for(int k=0;k<2;k++){temp.x[i][j]+=a.x[i][k]*b.x[k][j];temp.x[i][j]%=mod;}return temp;
}matrix k_powmatrix(matrix a,LL n)
{matrix temp;memset(temp.x,0,sizeof(temp.x));for(int i=0;i<2;i++)temp.x[i][i]=1;while(n){if(n&1)temp=mutimatrix(temp,a);a=mutimatrix(a,a);n>>=1;}return temp;
} int main()
{int n;while(cin>>n ){if(n==0) {cout<<"0\n";continue;}if(n==1||n==2) {cout<<"1\n";continue;}if(n==-1) return 0;matrix st;memset(st.x,0,sizeof(st.x));st.x[0][0]=1;st.x[0][1]=1;st.x[1][0]=1;st.x[1][1]=0;st=k_powmatrix(st,n);printf("%lld\n",(st.x[0][1]+mod)%mod);}
} 

2.如何通过矩阵快速幂解决这种递推问题
先看普通斐波那契
参考:https://blog.csdn.net/wust_zzwh/article/details/52058209
f(n)=f(n-1)+f(n-2)
f(1)=f(2)=1
其实这个是个递推式,那么我们只要找到他的通项,就可以求出n为任何值时候的f(n)
那这个递推式我们看不出他是等比还是等差数列,通项也不会求,此时就需要用矩阵
因为矩阵有一个性质,一个常数矩阵乘以一个矩阵A(n),结果是矩阵B(n)
那如果A中各个元素对应于B中各个元素满足,A(n)=B(n-1),那这个整体就是个等比数列啊
这里写图片描述
我们设an=这里写图片描述
上面看作是q*a(n-1)=an,由等比数列通项公式得到
q^(n-1)*a1=an
现在q我们已经有了,就剩找a1了,a1我们都会求,带特殊值么,假设n=2,a2=q*a1,然后我们就求出a1了,所以之后求an就先求q^(n-1),再求q^(n-1) *a1
因为我是学过线性代数的,其实这有个大问题,矩阵的左乘右乘结果不一样,为了方便起见,我们通项乘的次序应该和第一个递推式的次序一样

还有个例子
f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7.

Given A, B, and n, you are to calculate the value of f(n).
这里写图片描述

图片来自:https://www.cnblogs.com/Blackops/p/5468284.html
通过这一题我们明白一个事情,那就是对我们那个矩阵数列的优化,2* 1矩阵可以写成2* 2矩阵,这样的话我们不用再弄一个函数去求2* 1矩阵*2*2矩阵了
还有一点,关于n那个次幂的事,这都是看a1对应的那个n是几,根小学学的等比数列一样一样的。。
还有个小窍门,我们不用一上来就推f(n),可以通过f(1),f(2)推f(3),推完之后把3变成n,1变成n-2,2变成n-1,然后带4验证。如果是,那就是,然后继续ok
参考代码:
https://blog.csdn.net/elbadaernu/article/details/77899130

#include <iostream> 
#include <cstring>
#include <cstdio>
using namespace std; 
#define LL long long 
const int mod=7; 
struct matrix
{LL x[2][2];
};
matrix mutimatrix(matrix a,matrix b)
{matrix temp; memset(temp.x,0,sizeof(temp.x));    for(int i=0;i<2;i++)for(int j=0;j<2;j++)for(int k=0;k<2;k++){temp.x[i][j]+=a.x[i][k]*b.x[k][j];temp.x[i][j]%=mod;}return temp;
}matrix k_powmatrix(matrix a,LL n)
{matrix temp;memset(temp.x,0,sizeof(temp.x));for(int i=0;i<2;i++)temp.x[i][i]=1;while(n){if(n&1)temp=mutimatrix(temp,a);a=mutimatrix(a,a);n>>=1;}return temp;
} int main()
{int a,b,n;while(scanf("%d%d%d",&a,&b,&n)){if(!(a+b+n)) break;if(n<=2){printf("1\n");continue;}matrix st;memset(st.x,0,sizeof(st.x));st.x[0][0]=a;st.x[0][1]=1;st.x[1][0]=b;st.x[1][1]=0;matrix init;memset(init.x,0,sizeof(init.x));init.x[0][0]=1;init.x[0][1]=1;st=k_powmatrix(st,n-2);st=mutimatrix(init,st);printf("%lld\n",(st.x[0][0]+mod)%mod);}return 0; } 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/560668.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java ssm框架登录代码,求一个SSM框架登录功能的源码,要求能运行成功

[XML] 纯文本查看 复制代码<?xml version"1.0" encoding"UTF-8"?>xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xmlns:aop"http://www.springframework.org/schema/aop"xmlns:context"http://www.springframewo…

php getdbused,PHP之购物车

该文章记录了购物车的实现代码&#xff0c;仅供参考book_sc_fns.phpinclude_once(output_fns.php);include_once(book_fns.php);include_once(db_fns.php);include_once("user_auth_fns.php");include_once("admin_fns.php");include_once("data_vali…

java中spring的web支持nio,Spring WebClient NIO功能和问题域,与Spring Webflux一起使用

我正在使用最新版本的Spring - Spring 5 .我正在开发http客户端的WebService“聚合器”&#xff0c;有点像路由请求到外部WebServices&#xff0c;接收响应后接收响应&#xff0c;做一些数据操作并回复我的HTTP服务的客户端 .为了在我的应用程序中创建http客户端&#xff0c;我…

2018.9.15,Arduino—流水灯实验报告

实验任务和目的 通过Arduino控制LED形成流水灯效果 实验条件 Arduino UNO&#xff0c;面包板&#xff0c;6个LED&#xff0c;6个220Ω电阻 实验过程和结果 实验详细步骤&#xff1a; 在各LED正极和Arduino引脚之间串联一个限流电阻&#xff0c;并将LED负极与Arduion的GND相连 …

php封装redis类,php封装redis操作类

Redis系列-key相关主要操作函数_数学_自然科学_专业资料。这篇 blog 主要总结下,redis 中跟 key 相关的常用函数 1)keys 语法:keys pattern 解释:查找所有匹配指定......Redis 实现分析网易杭研——胡炜 OUTLINE ? REDIS的内部实现(基于2.8.7)––––––––– 单线程模型的…

liunx php apache2,linux apache2部署php

android-plugmgr源代码分析android-plugmgr是一个Android插件加载框架,它最大的特点就是对插件不需要进行任何约束.关于这个类库的介绍见作者博客,市面上也有一些插件加载框架,但是感觉没有这个好.在这篇文章中,我 ...JS延时提示框p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; fon…

2018.9.10.Matlab实验一:熟悉Matlab开发环境

一、实验任务和目的 1. 熟悉Matlab的系统环境及基本操作方法。 2. 掌握Matlab的搜索路径及其设置方法。 3. 熟悉Matlab的帮助信息的查阅方法。 二、实验内容 1. 熟悉 Matlab 工作界面的多个常用窗口的及使用方法。 熟悉Command windows、Workspace、Command history、C…

2018.9.10.Matlab实验二:Matlab基本运算

实验二&#xff1a;Matlab基本运算 一、实验任务和目的 1. 掌握变量的定义与数据类型。 2. 掌握变量的初始化方法。 3. 掌握数组、多维数组与子数组的定义、存储、赋值、变换。 4. 掌握逻辑数组的用法。 5. 熟悉MATLAB常用的函数、常用标点和快捷键。 二、实验内容 1. …

php进程数是指什么,25.查看php 某个服务的进程数

查看进程就是使用ps命令而已&#xff0c;只不顾ps的参数太多了。使用php查询的话&#xff0c;必须要开启几个函数(可以执行外部程序的函数)&#xff0c;参考官网&#xff1a;http://php.net/manual/zh/book.exec.php下面是在php进程中查询某个服务创建的进程数&#xff0c;比如…

2018.9.15,Matlab实验三:字符串、单元数组和结构体

一、实验任务和目的 掌握Matlab的字符串常用函数及其操作方法。掌握Matlab的结构体的基本操作方法。掌握Matlab的元胞数组的基本操作方法。 二、实验内容字符串数组Str[‘hopes, dreams, hold up, old up’]&#xff0c;查找’O’出现的次数和位置。现有三个字符串变量s1“i”…

c++ 不能分配给为0的数组_【嵌入式C】你有想过quot;数组下标quot;为何从0开始吗?...

1、聊一聊相信大家都有看过电影&#xff0c;今天所分享的是其经典背景音乐&#xff0c;或许音乐响起你又会想起那条单纯、善良的秋田犬&#xff01;今天跟大家聊聊一个有意思的话题&#xff0c;C中的数组下标为啥是从0开始?或者说为什么现在大部分的编程语言都会选择从0开始索…

oracle解析md5,Oracle中的MD5加密详解

一、技术点1、 DBMS_OBFUSCATION_TOOLKIT.MD5DBMS_OBFUSCATION_TOOLKIT.MD5是MD5编码的数据包函数&#xff0c;但偶在使用select DBMS_OBFUSCATION_TOOLKIT.MD5(input_string >abc) a from Dual时&#xff0c;却有错误提示&#xff0c;看来该函数只能直接在程序包中调用&…

2018.9.19.Matlab实验四:Matlab程序设计

一、实验任务和目的 熟悉程序设计思想。掌握伪代码的编写方法。掌握分支语句和循环结构的用法。 二、实验内容 输入一个百分制成绩&#xff0c;要求输出成绩等级A、B、C、D、E&#xff0c;其中90-100为A&#xff0c;80-89为B&#xff0c;70-79为C&#xff0c;60-69为D&#…

sata接口 图解 定义_SATA协议简介

SATA协议简介1、概述本文档主要介绍SATA的发展历程以及SATA相关协议&#xff0c;为后续SATA驱动框架分析做基础知识准备。2、SATA简介2.1 SATA发展历程2.1.1 PATA硬盘PATA硬盘叫做并行ATA硬盘(Parellel ATA)。为了限制其信号放大系统产生的高噪声&#xff0c;常采用高达5V的电压…

oracle 修改2个表,oracle学习笔记2:创建修改表

1.创建表CREATE TABLE ORDERINFO(ORDERID NUMBER(*, 0) NOT NULL, ORDERCODE VARCHAR2(20 BYTE) NOT NULL, USERID NUMBER(*, 0) NOT NULL, MOBILEPHONE VARCHAR2(20 BYTE) NOT NULL, ADDRESS VARCHAR2(128 BYTE) NOT NULL, PRODUCTNUMERIC NUMBER(*, 0) DEFAULT (0) NOT NULL,…

30岁软件测试转产品_SENSORO 产品总监回特入选 2019 年福布斯中国 30 岁以下精英榜...

日前&#xff0c;福布斯中国发布 2019 年度 30 岁以下精英榜&#xff08;30 Under 30&#xff09;&#xff0c;SENSORO&#xff08;北京升哲科技有限公司&#xff09;产品总监回特 成功入选 U30 精英榜企业科技版块。福布斯中国表示&#xff0c;今年技术领域人才辈出&#xff0…

Arduino实现数码管动态显示

之前一直以为公共端要么是解地要么是接电源&#xff08;3.3或5v&#xff09;&#xff0c;但是今天弄了半天我发现只要接口有电位差即可 没听课导致课堂作业没写出来&#xff0c;回来调了两个小时才完成 题目&#xff1a; 三位数码管从01亮到99&#xff0c;用arduino实现 分析…

pagehelper插件oracle,带你学习最简单的分页插件PageHelper

引言:PageHelper是国内非常优秀的一款开源的mybatis分页插件&#xff0c;它支持基本主流与常用的数据库&#xff0c; 例如mysql、 oracle、mariaDB、 DB2、 SQLite、Hsqldb等。今天墨白就给大家聊聊PageHelper这款分页插件,下面是PageHelper开源地址,感兴趣的小伙伴可以去看一下…

实验5matlab自定义函数的编写

问题 自定义一个函数&#xff0c;求给定复数的指数、对数、正弦和余弦&#xff0c;并在命令文件中调用该函数。自定义一个函数&#xff0c;计算一行向量中各元素的均值和标准差。求下列方程的根&#xff1a; f(z)exx2xx100.f(z) \ e^{x}x^{2}x^{\sqrt {x}}100\,. f(z) exx2xx…