首页 > 其他分享 >P1306 斐波那契公约数

P1306 斐波那契公约数

时间:2024-12-25 21:58:49浏览次数:6  
标签:begin end GCD int equation 斐波 P1306 bmatrix 那契

P1306 斐波那契公约数

对于 Fibonacci 数列:

\[ f_i = \begin{cases} [i = 1] & i \leq 1 \\ f_{i - 1} + f_{i - 2} & i \gt 1 \end{cases}\]

请求出 \(f_n\) 与 \(f_m\) 的最大公约数,即 \(\gcd(f_n, f_m)\)。

数据规模与约定

  • 对于 \(100\%\) 的数据,保证 \(1 \leq n, m \leq 10^9\)。

Solution:

我们先求Fib

首先我们知道一个东西叫做矩阵乘法,我们构造如下矩阵

\[\begin{equation} A =\begin{bmatrix} F[i] & F[i-1]\\ \end{bmatrix} \end{equation} \]

\[\begin{equation} I =\begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix} \end{equation} \]

\[\begin{equation} A*I =\begin{bmatrix} F[i]+F[i-1] & F[i] \\ \end{bmatrix} \end{equation} \]

\(\Longrightarrow\)

\[\begin{equation} A*I =\begin{bmatrix} F[i+1] & F[i] \\ \end{bmatrix} \end{equation} \]

然后我们根据辗转相减法求GCD不难推出 F[i+1] 与 F[i] 互质。

然后我们再推一些东西:

\[F[i]=a,F[i+1]=b \]

\[ \left\{ \begin{aligned} F[i+2]=1a+1b\\ F[i+3]=1a+2b\\ F[i+4]=2a+3b\\ F[i+5]=3a+5b\\ F[i+6]=5a+8b\\ \end{aligned} \right. \]

\[F[m]=F[m-i-1]a+F[m-i]b \]

\(GCD(F[n],F[m])=GCD(F[n],F[m-n]*F[n+1])\)

\(\Longrightarrow\)

\(GCD(F[n],F[m])=GCD(F[n],F[m-n])\)

利用辗转相减法把这个式子递归下去,就会得到:

\(GCD(F[n],F[m])=F[GCD(n,m)]\)

然后这题就做完了

Code:

#include<bits/stdc++.h>
#define int long long
const int N=105;
const int mod=1e8;
using namespace std;
int n=2,k;
struct Matrix{
    int a[N][N];
}ANS;
Matrix operator *(const Matrix &A,const Matrix &B)
{
    Matrix res={{0}};
    for(int i=1;i<=n;i++)for(int k=1;k<=n;k++)for(int j=1;j<=n;j++)
    {
        res.a[i][j]+=(A.a[i][k]%mod)*(B.a[k][j]%mod);
        res.a[i][j]%=mod;
    }
    return res;
}
Matrix qpow(Matrix x,int k)
{
    Matrix K={{0}};
    K.a[1][1]=K.a[1][2]=1;
    K.a[2][1]=1;
    if(k<=0){for(int i=1;i<=n;i++)x.a[i][i]=1;return x;}
    while(k)
    {
        if(k&1)
        {
            x=x*K;
        }
        K=K*K;
        k>>=1;
    }
    return x;
}
void init()
{
    for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)
    {
        ANS.a[i][j]=0;
    }
    for(int i=1;i<=n;i++)ANS.a[i][1]=1;
}
int x,y;
int gcd(int x,int y){return y==0 ? x : gcd(y,x%y);}
void work()
{
    cin>>x>>y;
    init();
    x=gcd(x,y);
    ANS=qpow(ANS,x-1);
    printf("%lld\n",ANS.a[1][1]);
}
#undef int
int main()
{
    //freopen("P1939.in","r",stdin);freopen("P1939.out","w",stdout);
    work();
    return 0;
}

标签:begin,end,GCD,int,equation,斐波,P1306,bmatrix,那契
From: https://www.cnblogs.com/LG017/p/18631505

相关文章

  • 斐波那契查找算法
    1,什么是斐波那契查找算法?    斐波那契查找算法(FibonacciSearch)是一种基于斐波那契数列的搜索算法。与二分查找算法相比,斐波那契查找更适用于没有直接索引访问的数据结构(如链表)。它通过使用斐波那契数列来逐步缩小搜索范围,从而找到目标元素的位置。斐波那契数列斐......
  • 动态规划在斐波那契数列中的应用与优化
    文章目录前言......
  • 用C语言输出 -- 斐波那契
    首先,你要明白什么是斐波那契数列:斐波那契数列是指这样一个数列:1,1,2,3,5,8,13,21,34,55,89……这个数列从第3项开始,每一项都等于前两项之和。源代码如下:#include<stdio.h>intmain(){ inti,n,a=1,b=1,c; printf("输入显示个数\n"); scanf("%d",&n); for(i=1;i<=n;......
  • LeetCode | 斐波那契数
    Problem:509.斐波那契数题目斐波那契数(通常用F(n)表示)形成的序列称为斐波那契数列。该数列由0和1开始,后面的每一项数字都是前面两项数字的和。也就是:F(0)=0,F(1)=1F(n)=F(n-1)+F(n-2),其中n>1给定n,请计算F(n)。示例1:输入:n=2输出:1解......
  • 斐波那契数列c++
    意大利数学家斐波那契(LeonardoFibonacci)是12、13世纪欧洲数学界的代表人物。他提出的“兔子问题”引起了后人的极大兴趣。“兔子问题”假定一对大兔子每一个月可以生一对小兔子,而小兔子出生后两个月就有繁殖能力,问从一对小兔子开始,n个月后能繁殖成多少对兔子?输入格式:首先......
  • 1137. 第 N 个泰波那契数
    题目如下:https://leetcode.cn/problems/n-th-tribonacci-number/description/?envType=study-plan-v2&envId=dynamic-programming思路:动态规划Java代码如下:`importjava.util.Scanner;classSolution{publicstaticvoidmain(String[]args){Scannerscanner=newScan......
  • 509. 斐波那契数
    题目如下:https://leetcode.cn/problems/fibonacci-number/?envType=study-plan-v2&envId=dynamic-programming思路:动态规划Java代码如下:`importjava.util.Scanner;publicclassSolution{publicstaticvoidmain(String[]args){Scannerscanner=newScanner(System.......
  • LeetCode LCR126[斐波那契数]
    题目链接LeetCodeLCR126[斐波那契数]详情实例提示题解思路首先想到用递归来求解,F(n)=F(n-1)+F(n-2)但是吧,一看提示啊,0<=n<=100,递归执行100次,那肯定是会超时的噻所以单纯递归肯定是不可行的,此处我采用循环代替递归当n=0时,返回0当n=1时,返回1......
  • LeetCode 509[斐波那契数]
    题目链接LeetCode509[斐波那契数]详情实例提示题解思路递归求值,但是吧,如果是用递归的话有可能会造成内存超出限制的错误,当然我不能确定会不会报此错误,因为我没有试过此处我是用循环代替递归的n为0时,fn为0n为1时,fn为1n为2时,fn为fn_1+fn_2=0+1=1n为3时,fn为......
  • 7-187 斐波那契数列
    任务描述:斐波那契数列是指这样的一个数列:1,1,2,3,5,8,13,21,...,这个数列从第3个数开始每个数都等于前两个数的和,请输出这个数列的前20项。输入格式:没有输入。输出格式:数据占域宽为8,每行输出5个数。输入样例:在这里给出一组输入。例如:输出样例:在这里给出相应的输出。例如:......