原题链接

嗯...很多人应该是冲着这个标题来的

(斐波那契的魅力)

1.分析题面

点开题目,浏览一遍题目,嗯?这么简单?还是蓝题?

再看看数据范围,感受出题人深深的好意...

\(n,m \leq 10^9\)

就算加上矩阵快速幂,\(fib[1000000000]\) 也不是高精度能存的下的。

所以,我们得想一点技巧。

2.寻找思路

深呼吸,思考学过的斐波那契数列的性质...(???)

......

终于,它出现了!

\(gcd(fib[x],fib[y])=fib[gcd(x,y)]\)

怎么证呢?

证明:先证明斐波那契数列相邻两项是互素的。

  • 反证法。若不互素,设\(x=gcd(fib[i],fib[i-1]),x>1\)

    则\(x|fib[i],x|fib[i-1]\)

    又因为\(fib[i-2]=fib[i]-fib[i-1]\)

    所以\(x|fib[i-2]\)

    一直往前推,直到\(x|fib[2]\)

    又因为\(fib[2]=1\)

    所以\(x=1\),矛盾!

接着,证明\(fib[n]=fib[m] fib[n-m+1]+fib[m-1] fib[n-m]\)

  • \(fib[n]=fib[n-1]+fib[n-2]\)

    \(fib[n]=2fib[n-2]+fib[n-3]\)

    \(fib[n]=3fib[n-3]+2fib[n-4]\)

    ...

    \(fib[n]=fib[m] fib[n-m+1]+fib[m-1] fib[n-m]\)

最后,来到了对原公式的证明:

  • \(gcd(fib[x],fib[y])\)

    \(=gcd(fib[y]fib[x-y+1]+fib[y-1]fib[x-y],fib[y])\)

    \(=gcd(fib[x-y],f[y])\)(因为\(fib[y-1]\)与\(fib[y]\)互质)

    以此递推下去,得:

    \(=gcd(fib[x mod y],f[y])\)

    这不是辗转相除吗?以此类推,最后会得到:

    \(=gcd(fib[0],fib[gcd(x,y)])\)

    \(=fib[gcd(x,y)]\)

呼,总算证完了~~

接下来,求\(fib[i]\),应该不要多讲了吧?矩阵快速幂就行了啊!

没学过的同学看这里:矩阵快速幂(原理+模板)

3.代码实现

终于来到了code time了呢~~

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int mod=1e8;
struct Matrix{
long long matrix[105][105];
int x,y;
Matrix(const long long a[105][105],int xx,int yy){
for(int i=1;i<=xx;i++){
for(int j=1;j<=yy;j++){
matrix[i][j]=a[i][j];
}
}
x=xx,y=yy;
}
Matrix(int fill,int xx,int yy){
for(int i=1;i<=xx;i++){
for(int j=1;j<=yy;j++){
matrix[i][j]=fill;
}
}
x=xx,y=yy;
}
Matrix(){
x=y=0;
memset(matrix,0,sizeof(matrix));
}
Matrix operator*(const Matrix& a) const{
Matrix ans;
for(int i=1;i<=x;i++){
for(int j=1;j<=a.y;j++){
ans.matrix[i][j]=0;
for(int k=1;k<=y;k++){
ans.matrix[i][j]+=matrix[i][k]*a.matrix[k][j];
ans.matrix[i][j]%=mod;
}
}
}
ans.x=x,ans.y=a.y;
return ans;
}
Matrix operator%(const int& a) const{
Matrix ans;
for(int i=1;i<=x;i++){
for(int j=1;j<=y;j++){
ans.matrix[i][j]=matrix[i][j]%a;
}
}
return *this;
}
Matrix operator^(const long long& a) const{
Matrix ans(1,x,y),power(*this);
for(int i=1;i<=x;i++){
for(int j=1;j<=y;j++){
if(i!=j) ans.matrix[i][j]=0;
}
}
long long tmp=a;
while(tmp){
if(tmp&1){
ans=ans*power;
ans=ans%mod;
}
power=power*power;
tmp>>=1;
power=power%mod;
}
return ans;
}
}m;
long long n,k,p;
int t;
const long long d[105][105]={\
{0,0,0},
{0,1,1},
{0,1,0}
};
Matrix c(1,2,1);
int gcd(int a,int b){
return b==0?a:gcd(b,a%b);
} int main(){
Matrix m(d,2,2);
cin>>n>>p;
k=gcd(n,p);
if(k<=2) {
cout<<1<<endl;
return 0;
}
Matrix ans=c*(m^(k-1));
cout<<ans.matrix[1][1]<<endl;
return 0;
}

蒟蒻写博客不易,还请各位大佬点个赞~~

【Luogu】P1306 斐波那契公约数 题解的更多相关文章

  1. Luogu P1306 斐波那契公约数

    这道题其实是真的数学巨佬才撸的出来的题目了 但如果只知道结论但是不知道推导过程的我感觉证明无望 首先这道题肯定不能直接搞,而且题目明确说明了一些方法的问题 所以就暗示我们直接上矩阵了啦 但是如果直接搞 ...

  2. 【luogu P1306 斐波那契公约数】 题解

    题目链接:https://www.luogu.org/problemnew/show/P1306#sub gcd(f[m],f[n]) = f[gcd(m,n)] #include <iostr ...

  3. 洛谷 P1306 斐波那契公约数 题解

    题面 结论:gcd(F[n],F[m])=F[gcd(n,m)]; F[n]=a和F[n+1]=b F[n+2]=a+b,F[n+3]=a+2b,…F[m]=F[m?n?1]a+F[m?n]b F[n ...

  4. 洛谷 P1306 斐波那契公约数

    洛谷 P1306 斐波那契公约数 题目描述 对于Fibonacci数列:1,1,2,3,5,8,13......大家应该很熟悉吧~~~但是现在有一个很“简单”问题:第n项和第m项的最大公约数是多少? ...

  5. 洛谷- P1306 斐波那契公约数 - 矩阵快速幂 斐波那契性质

    P1306 斐波那契公约数:https://www.luogu.org/problemnew/show/P1306 这道题目就是求第n项和第m项的斐波那契数字,然后让这两个数求GCD,输出答案的后8位 ...

  6. 洛谷 P1306 斐波那契公约数 解题报告

    P1306 斐波那契公约数 题意:求\(Fibonacci\)数列第\(n\)项和第\(m\)项的最大公约数的最后8位. 数据范围:\(1<=n,m<=10^9\) 一些很有趣的性质 引理 ...

  7. 洛谷——P1306 斐波那契公约数

    P1306 斐波那契公约数 题目描述 对于Fibonacci数列:1,1,2,3,5,8,13......大家应该很熟悉吧~~~但是现在有一个很“简单”问题:第n项和第m项的最大公约数是多少? 输入输 ...

  8. P1306 斐波那契公约数

    题目描述 对于Fibonacci数列:1,1,2,3,5,8,13......大家应该很熟悉吧~~~但是现在有一个很“简单”问题:第n项和第m项的最大公约数是多少? 输入输出格式 输入格式: 两个正整 ...

  9. 【Luogu】P1306斐波那契公约数(递推)

    题目链接 有个定理叫gcd(f(n),f(m))=f(gcd(n,m)) 所以递推就好了. #include<cstdio> #include<cstdlib> #includ ...

随机推荐

  1. 005 01 Android 零基础入门 01 Java基础语法 01 Java初识 05 Eclipse简介

    005 01 Android 零基础入门 01 Java基础语法 01 Java初识 05 Eclipse简介 Eclipse是一款集成开发工具--IDE. 集成开发环境(IDE,Integrated ...

  2. I2C 方式

    转自:http://www.cnblogs.com/lucky-apple/archive/2008/07/03/1234581.html 区别: SPI:高速同步串行口.3-4线接口,收发独立.可同 ...

  3. 2-K8S常用命令

    kubectl 命令行管理工具 类型 命令 描述 基础命令 create 通过文件名或标准输入创建资源 expose 为Deployment,Pod创建service run 在集群中运行一个特定的镜 ...

  4. python之线程了解部分

    一.死锁(了解) 死锁产生的4个必要条件: 互斥:一个资源同一时刻只允许一个线程进行访问 占有未释放:一个线程占有资源,且没有释放资源 不可抢占:一个已经占有资源的线程无法抢占到其他线程拥有的资源 循 ...

  5. MeteoInfoLab脚本示例:计算水平螺旋度

    尝试了用MeteoInfoLab编写计算水平螺旋度的脚本,结果未经验证.脚本程序: print 'Open data files...' f_uwnd = addfile('D:/Temp/nc/uw ...

  6. pytest文档40-pytest.ini配置用例查找规则(面试题)

    前言 面试题:pytest如何执行不是test开头的用例?如执行 xxx_*.py这种文件的用例. pytest.ini 配置文件可以修改用例的匹配规则. pytest命令行参数 cmd打开输入pyt ...

  7. Python可迭代对象和迭代器对象

    可迭代对象iterable: 对象字面意思:Python中一切皆对象.一个实实在在存在的值. 可迭代:更新迭代.迭代是一个重复的过程,每次重复是基于上一次的结果而继续的,每次都有新的内容. 可迭代对象 ...

  8. Vue实例中封装api接口的思路 在页面中用async,await调用方法请求

    一般我们写小型的项目是用不到封装axios实例 但是当我们写大型项目时  接口有时候多到有上百个接口,那我们在请求一次调用一次接口,接口上好多都是重复的,这个时候我们就可以封装axios实例,既节省了 ...

  9. Spring+Hibernate+Struts2整合之实现登录功能

    前端代码: <form id="loginForm" action="${ pageContext.request.contextPath }/user_login ...

  10. Bitmap缩放(三)

    质量压缩 public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle ...