(矩阵快速幂)解所有类似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,一经查实,立即删除!

相关文章

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…

2018.9.15,Arduino—流水灯实验报告

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

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. …

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开始索…

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的电压…

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

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

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…

ic读卡器设置工具_从Matlab被禁来看,给IC教育带来哪些启发?

在上周五看到朋友圈转发包云岗老师就Matlab被禁后在某论坛的发言&#xff0c;在阅读的当时就很有感触&#xff0c;本想当晚就写点东西&#xff0c;不曾想拖到了现在。包老师的梳理的几个点&#xff0c;是结合教学和应用来谈的。在IC教育培训方面&#xff0c;我对这些观点也深以…

arduino光敏+LED+数码管+蜂鸣器综合实验

内容 用光敏控制LED的明暗程度&#xff0c;光敏值在3位数码管上显示&#xff0c;串口输出光敏值&#xff0c;蜂鸣器到一定的值会didi 话不多说&#xff0c;直接上代码&#xff0c;那几个部分拼到一起&#xff0c;多了个数的拆分&#xff0c;让k1k2k3分别等于百位十位个位 代…

server sql 水平分表_springboot集成Shardingsphere进行分库分表

当公司业务量上去之后&#xff0c;单表支撑不了的时候&#xff0c;分库分表就是一个绕不开的话题&#xff0c;小弟最近新入职一家公司&#xff0c;发现这边公司在用ShardingSphere来进行分库分表&#xff0c;之前没接触过这方面&#xff0c;所以就写了个demo学习一下&#xff0…

网鼎杯2020php反序列化,2020-网鼎杯(青龙组)_Web题目 AreUserialz Writeup

0x02 AreUSerialz关于s大写小写问题&#xff0c;可以看p神在圈子里发的&#xff0c;我在最后付上截图考点: php反序列化 php特性 利用链构造1.打开页面得到代码如下:include("flag.php");highlight_file(__FILE__);class FileHandler {protected $op;protected $file…

利用matlab绘制图形

目前存在的一些问题&#xff1a; 1.第一题的两个图像无法重叠 2.最后一个题的第一个图是六瓣&#xff0c;而我写的是八瓣 感谢张同学给我指出来&#xff0c;目前我正在思考解决方法 第一个的话我以为把框缩小就可以重叠了&#xff0c;但是今天试了一下还是分开的&#xff0c;还…

matlab guide对话框+滑动条+弹出式菜单+列表框的使用

文章目录前言matlab数据传递概观对话框创建利用滑动条实现颜色调控利用弹出式菜单选择并输入文本框利用列表框选择并输入文本框前言 我觉得gui无非就是给程序加了件衣服&#xff0c;其实具体的程序我们都会写&#xff0c;我们唯一不明白的是那几个部分数据之间的传递&#xff…

流放之路材质过滤怎么设置_松下除湿机怎么样 松下除湿机款式有哪些型号【详解】...

马上南方就要进入梅雨季节了&#xff0c;潮湿的天气容易滋生细菌&#xff0c;可能会导致人们出现过敏现象&#xff0c;所以很多家庭都选择购买除湿机&#xff0c;现在市场上的除湿机不是很多&#xff0c;其中松下的除湿机比较受欢迎&#xff0c;所以小编我就来跟大家说一说松下…

matlab图形句柄+图形对象+图形对象的属性+对象操作

文章目录前言&#xff1a;图形对象&#xff1a;图形句柄&#xff1a;图形对象的属性&#xff1a;对象的基本操作figure对象(图形窗口)figure()函数&#xff1a;clf()函数清空当前图形窗口&#xff1a;axes坐标轴对象image()line()text()前言&#xff1a; 下面这些是为了更好地…