Luogu P1306 斐波那契公约数

这道题其实是真的数学巨佬才撸的出来的题目了

但如果只知道结论但是不知道推导过程的我感觉证明无望

首先这道题肯定不能直接搞,而且题目明确说明了一些方法的问题

所以就暗示我们直接上矩阵了啦

但是如果直接搞还要高精度,不仅很烦而且绝壁TLE

所以我们引出性质,其中f[x]表示斐波那契数列的第x项:

gcd(f[n],f[m])=f[gcd(n,m)]

具体的超详细的证明戳这里

然后题意相当于对f[gcd(n,m)]取膜1e9,就是最基本的矩阵优化了

关于矩阵优化斐波那契的板子题看这里

关于这题的CODE,因为那天晚上在Linux机子上打的,被强制转码风了,而且Tab还是两个空格

CODE

#include<cstdio>
#include<cstring>
using namespace std;
typedef long long LL;
const int N=3,mod=1e8;
int n,m;
struct Matrix{
  int n,m;
  LL a[N][N];
  inline void Fb_init(void){
    n=m=2; a[1][1]=0; a[1][2]=a[2][1]=a[2][2]=1;
  }
  inline void cri_init(void){
    n=m=2; a[1][1]=a[2][2]=1; a[1][2]=a[2][1]=0;
  }
};
inline Matrix mul(Matrix A,Matrix B){
  Matrix C; C.n=A.n; C.m=B.m; memset(C.a,0,sizeof(C.a));
  for (register int i=1;i<=C.n;++i)
    for (register int j=1;j<=C.m;++j)
      for (register int k=1;k<=A.m;++k)
    C.a[i][j]=(C.a[i][j]+A.a[i][k]*B.a[k][j])%mod;
  return C;
}
inline Matrix quick_pow(Matrix A,int p){
  Matrix T; T.cri_init();
  while (p){
    if (p&1) T=mul(T,A);
    A=mul(A,A); p>>=1;
  }
  return T;
}
inline int gcd(int n,int m){
  return m?gcd(m,n%m):n;
}
int main(){
  //freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
  scanf("%d%d",&n,&m); n=gcd(n,m);
  if (n<=2) { puts("1"); return 0; }
  Matrix A; A.Fb_init();
  A=quick_pow(A,n-2);
  printf("%lld",(A.a[2][1]+A.a[2][2])%mod);
  return 0;
}

原文地址:https://www.cnblogs.com/cjjsb/p/9082334.html

时间: 2024-10-03 22:29:36

Luogu P1306 斐波那契公约数的相关文章

洛谷P1306 斐波那契公约数

P1306 斐波那契公约数 题目描述 对于Fibonacci数列:1,1,2,3,5,8,13......大家应该很熟悉吧~~~但是现在有一个很“简单”问题:第n项和第m项的最大公约数是多少? 输入输出格式 输入格式: 两个正整数n和m.(n,m<=10^9) 注意:数据很大 输出格式: Fn和Fm的最大公约数. 由于看了大数字就头晕,所以只要输出最后的8位数字就可以了. 输入输出样例 输入样例#1: 4 7 输出样例#1: 1 说明 用递归&递推会超时 用通项公式也会超时 /* 首先,斐波

P1306 斐波那契公约数

题意 求斐波那契数列第n项和第m项的最大公约数 题解 设斐波那契数列第x项为F[x] 则有结论\(Gcd(F[n], F[m]) = F[Gcd(n, m)]\) 证明: 不妨设n < m 则\(F[m] = F[m-1] +F[m-2]\) \(= 2*F[m-2] + F[m-3]\) \(= 3*F[m-3] + 2*F[m-4]\) \(=...\) \(= F[x+1]*F[m-x] + F[x] * F[\) 代码 #include <cstdio> typedef long

P1306 斐波那契公约数(ksm+结论)

题目描述 对于Fibonacci数列:1,1,2,3,5,8,13......大家应该很熟悉吧~~~但是现在有一个很“简单”问题:第n项和第m项的最大公约数是多少? Update:加入了一组数据. 输入输出格式 输入格式: 两个正整数n和m.(n,m<=10^9) 注意:数据很大 输出格式: Fn和Fm的最大公约数. 由于看了大数字就头晕,所以只要输出最后的8位数字就可以了. 输入输出样例 输入样例#1: 复制 4 7 输出样例#1: 复制 1 结论:gcd(F[n],F[m])=F[gcd(n

luogu P1962 斐波那契数列

二次联通门 : luogu P1962 斐波那契数列 /* luogu P1962 斐波那契数列 矩阵快速幂求feibonacii 矩阵为 1 1 1 0 做N - 2次方就好 */ #include <cstdio> #define Mod 1000000007 #define Max 2 void read (long long &now) { now = 0; register char word = getchar (); while (word < '0' || wor

[luogu]P3938 斐波那契[数学]

[luogu]P3938 斐波那契 题目描述 小 C 养了一些很可爱的兔子. 有一天,小 C 突然发现兔子们都是严格按照伟大的数学家斐波那契提出的模型来进行 繁衍:一对兔子从出生后第二个月起,每个月刚开始的时候都会产下一对小兔子.我们假定, 在整个过程中兔子不会出现任何意外. 小 C 把兔子按出生顺序,把兔子们从 1 开始标号,并且小 C 的兔子都是 1 号兔子和 1 号兔子的后代.如果某两对兔子是同时出生的,那么小 C 会将父母标号更小的一对优先标 号. 如果我们把这种关系用图画下来,前六个月

斐波那契公约数的相关证明

\(\text{来一波斐波那契公约数的证明}QwQ\) \(\text{已知} \{F_n\} \text{为斐波那契数列,求证:}\) \[\forall\ n,m\in\text{Z}^{+},(F_n,F_m)=F_{(n,m)}\] \(\text{证明:}\) \(\text{令}\) \(n<m\) \(\text{用 }F_n\text{ 和 }F_{n+1}\text{ 表示 } F_{n+2},F_{n+3},F_{n+4},\cdots\) \[F_{n+2}=F_n+F_{

【斐波那契】【矩阵快速幂模板】斐波那契公约数

这道题求第n项和第m项斐波那契的公约数这里有一个定理(n,m都是1e9) gcd(f[m],f[n])=f[gcd(n,m)] 斐波那契使用矩阵快速幂求 #include <bits/stdc++.h> #define ll long long #define ull unsigned long long #define ld long double using namespace std; const int maxn=20010; const int NIL=0; const int mo

斐波那契公约数(luogu 1306)

题目描述 对于Fibonacci数列:1,1,2,3,5,8,13......大家应该很熟悉吧~~~但是现在有一个很"简单"问题:第n项和第m项的最大公约数是多少? Update:加入了一组数据. 输入输出格式 输入格式: 两个正整数n和m.(n,m<=10^9) 注意:数据很大 输出格式: Fn和Fm的最大公约数. 由于看了大数字就头晕,所以只要输出最后的8位数字就可以了. 输入输出样例 输入样例 4 7 输出样例 1 说明 用递归&递推会超时 用通项公式也会超时 co

[Luogu] 广义斐波那契数列

https://www.luogu.org/problemnew/show/P1349 题解:https://www.zybuluo.com/wsndy-xx/note/1152988 原文地址:https://www.cnblogs.com/shandongs1/p/9059210.html