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

P1306 斐波那契公约数 题解

时间:2023-06-11 22:48:00浏览次数:46  
标签:include gcd int 题解 clear 斐波 therefore 那契 引理

请求出 \(f_n\) 与 \(f_m\) 的最大公约数,即 \(\gcd(f_n, f_m)\),答案对 \(10^8\) 取模。

结论:\(\gcd(f_n, f_m) = f_{\gcd(n, m)}\)

证明如下:

首先引理 1:

\[f_{n + m} = f_{n - 1} \times f_{m} + f_{n}\times f_{m + 1} \]

运用归纳法,可以简单证明,此处略去。

引理 2:

\[\gcd(f_n, f_{n + 1}) = 1\\ \]

运用归纳法:

\(\gcd(f_1, f_{2}) = 1\) 平凡成立。

设现已有 \(\gcd(f_{n - 1}, f_n) = 1\),则

\(\gcd(f_n, f_{n + 1}) =\gcd(f_n, f_{n - 1} + f_n) = \gcd(f_{n - 1}, f_n) = 1\)

证毕。

\[\begin{aligned} 由引理 1知,f_{m} =& f_{n - m - 1} f_{n} + f_{n - m} f_{n + 1}\\ \therefore \gcd(f_n, f_m) = &\gcd(f_n, f_{n - m - 1} f_{n} + f_{n - m} f_{n + 1})\\ \because f_n | f_{n - m - 1} f_{n}\\ \therefore \gcd(f_n, f_m) = &\gcd(f_n, f_{n - m} f_{n + 1})\\ 由引理 2知,\gcd(f_n, f_{n + 1}) = 1\\ \therefore\gcd(f_n, f_m) = &\gcd(f_n, f_{n - m})\\ \gcd(f_n, f_m) = &\gcd(f_{n - m}, f_n)\\ \therefore \gcd(f_n, f_m) = &\gcd(f_{n\ \bmod\ m}, f_n)\\ 如此递归,最后结果为 \gcd(f_n, f_m) = &\gcd(f_{\gcd(n, m)}, 0) = f_{\gcd(n, m)}\\ 此处可类比欧几里得算法 \end{aligned} \]

最后用矩阵算 \(f_{\gcd(n, m)}\) 即可。

#include <algorithm>
#include <cstring>
#include <iostream>
#define speedup (ios::sync_with_stdio(0), cin.tie(0), cout.tie(0))
#define int long long
using namespace std;

const int mod = 1e8;

struct Mat
{
    int m[5][5];
    int r, c;
    void clear(int R, int C)
    {
        memset(m, 0, sizeof m);
        r = R, c = C;
    }
    void init()
    {
        for (int i = 0; i <= min(r, c); i++)
            m[i][i] = 1;
    }
    friend Mat operator*(const Mat a, const Mat b)
    {
        Mat res;
        res.clear(a.r, b.c);
        for (int i = 1; i <= a.r; i++)
            for (int j = 1; j <= b.c; j++)
                for (int k = 1; k <= a.c; k++)
                    res.m[i][j] = (res.m[i][j] + a.m[i][k] * b.m[k][j] % mod) % mod;
        return res;
    }
} M, A;

Mat qmi(Mat a, int b)
{
    Mat res;
    res.clear(3, 3), res.init();
    while (b)
    {
        if (b & 1)
            res = res * a;
        b >>= 1;
        a = a * a;
    }
    return res;
}

signed main()
{
    speedup;
    int n, m;
    cin >> n >> m;
    M.clear(2, 2);
    M.m[1][2] = M.m[2][1] = M.m[2][2] = 1;
    A.clear(2, 1);
    A.m[2][1] = 1;
    A = qmi(M, __gcd(n, m) - 1) * A;
    cout << A.m[2][1] << '\n';

    return 0;
}

标签:include,gcd,int,题解,clear,斐波,therefore,那契,引理
From: https://www.cnblogs.com/MoyouSayuki/p/17473778.html

相关文章

  • AtCoder Beginner Contest 305 题解
    https://atcoder.jp/contests/abc305/tasks_printE-ArtGalleryonGraph冷知识:md这题赛时没做出来/cy刚看到题:这是什么题啊,\(K,h\)都\(1e5\)能做吗/fn确实能做。考虑类似SPFA的操作。设\(a_x\)表示\(x\)还可以对距离最多为\(a_x\)的点产生贡献,然后就直接......
  • Codeforces Round 876 Div2 A-D题解
    CodeforcesRound876Div2A-D题解A.TheGoodArray这个题就是问你对于\(i\leqn\),要求前面后面至少\(ceil(\frac{i}{k})\)个1那我们就贪心的每k个放一个1,或者直接用数学算一下就好了AC代码#include<bits/stdc++.h>usingnamespacestd;constexprintlimit=(......
  • Java8新特性Stream之list转map及问题解决
    List集合转Map,用到的是Stream中Collectors的toMap方法:Collectors.toMap具体用法实例如下://声明一个List集合Listlist=newArrayList();list.add(newPerson("1001","小A"));list.add(newPerson("1002","小B"));list.add(......
  • 杂题题解
    序列变化(exchange)只要第一位确定,后面的\(n-1\)位都是唯一确定的。因为具体是B还是C只取决于两侧字母是否一样,所以两种变化方案其中一种是另一种每一位取反,要么都合法,要么都不合法。但变化出的方案可能不能继续变化下去,比如CCC变化到BBB之后就不能再变化了,但变化到CCC......
  • permu题解(树上莫队)(非正解)
    题目传送门题意给出一个长度为$n$的排列$P(P1,P2,...Pn)$,以及$m$个询问。每次询问某个区间$[l,r]$中,最长的值域连续段长度。思路首先这道题事求连续段的长度,打个莫队先#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;namespaceTestify{ inlineint......
  • mysql运行sql文件时,timestamp默认值出错问题解决
    出现了---Invaliddefaultvaluefor'reward_time' 直接打开sql文件,将字段reward_time类型值替换成NULL即可 ......
  • 和与积 题解 简单二分查找
    题目大意:给定两个整数\(a(2\lea\le2\times10^9)\)和\(b(1\leb\le10^{18})\)。判断是否存在两个正整数\(x\)和\(y\),同时满足如下两个条件:\(x+y=a\)\(x\timesy=b\)解题思路:用\(a-x\)表示\(y\),可以得到面积的表达式为\(x\times(a-x)\),然后......
  • 佳佳的 Fibonacci 题解
    佳佳的Fibonacci题解题目:题解:数据范围很大,暴力超时,考虑的是矩阵优化递推,关键是求出递推矩阵,然后结合矩阵快速幂求解如何求解递推矩阵?我们首先知道斐波那契的递推式:f[i]=f[i-1]+f[i-2]——>①然后题目中给我们了T(n)的递推式:T(n)=F[1]+2F[2]+3F[3]+...+nF[n]——>②考......
  • 题解 NOD2207C【不降序列】
    problem给出n个数组A1​到An​,数组中的元素为1到M之间的数字。数组之间也存在字典序,即从第一个数开始逐位比较,一旦某个数字大于另一个,则数组的字典序大于另一个,如果某一个是另一个的前缀,则前缀的字典序更小。你可以选择一些大于0的数字执行减法操作,一旦选中某个数......
  • 题解 NOD2207D【电报】
    前置知识:高斯消元已知\(n\)元线性一次方程组。关于\(x_1,x_2,\cdots,x_n\)。\[\begin{cases}a_{1,1}x_1+a_{1,2}x_2+\cdots+a_{1,n}x_n=b_1\\a_{2,1}x_1+a_{2,2}x_2+\cdots+a_{2,n}x_n=b_2\\\cdots\\a_{n,1}x_1+a_{n,2}x_2+\cdots......