gcd fib

小岛【】发了篇日志,说一个问题。
lcm(fib(a1),fib(a2),...,fib(an))mod(109+7)

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1355
https://www.hackerrank.com/contests/infinitum10/challenges/fibonacci-lcm

https://www.codechef.com/problems/FLCM/
https://www.hackerrank.com/contests/infinitum9/challenges/fibonacci-gcd/editorial


最后的是问题的解决,然而是个英文的。
那么我具体的解释解释……

总而言之是先解决 gcd(...) ,然后喜闻乐见的: lcm=fac/gcd
而解决 gcd 的关键是这样一个公式:

gcd(fib(a),fib(b))=fib(gcd(a,b))

这个属于 fib 数的常见性质。 Acdreamer 大大的博客上有过记载: http://blog.youkuaiyun.com/acdreamers/article/details/7909480

它的证明也不复杂。这里就介绍一下。
有这样的关系:

(1110)n=(fibn+1fibnfibnfibn1)

那么:
(1110)a+b=(fiba+b+1fiba+bfiba+bfiba+b1)

(1110)a+b=(fiba+1fibafibafiba1)(fibb+1fibbfibbfibb1)

这样就有了:
fib(a+b)=fin(a+1)fib(b)+fib(a)fib(b1)

gcd(fib(a),fib(b)) a>b 的状况下把 fib(a) 写作 fib(ab+b) ,利用上面的公式得到:
gcd(fib(a),fib(b))=gcd(fib(ab)fib(b1),fib(b))

然而我们有:
gcd(fib(b),fib(b1))=gcd(fib(b2),fib(b1))=gcd(fib(b1),fib(b2))=...=gcd(1,0)=1

其中总结到的 gcd(fib(n),fib(n1))=1 也是值得注意的性质。
于是我么得到了:
gcd(fib(a),fib(b))=gcd(fib(b),fib(ab))

迭代上面式子的过程若干次,就可以得到:
gcd(fib(a),fib(b))=gcd(fib(b),fib(a mod b))

我们发现了这样的格式:
f(a,b)=fib(a),b=0f(a,b)=f(b,a mod b),else

欧几里得算法告诉我们:
gcd(fib(a),fib(b))=fib(gcd(a,b))

详细来说就是:
fib1f(a,b)=a,b=0fib1f(a,b)=fib1f(b,a mod b),else

说明
fib1f(a,b)=gcd(a,b)

f(a,b)=fib(gcd(a,b))

# U501347 「Stoi2025」爱的飞行日记 ## 题目背景 ![](bilibili:BV1fx411N7bU?page=125) ## 题目描述 $t$ 组询问,每次询问给定正整数 $n,m$,计算 $$\prod_{a_1=1}^{m}\prod_{a_2=1}^{m}\cdots\prod_{a_n=1}^{m}\operatorname{lcm}(f_{a_1},f_{a_2},\dots,f_{a_n})\bmod{37426667}$$ 的值。其中 $f_i$ 是斐波那契数,满足 $f_1=f_2=1$,且 $f_i=f_{i-1}+f_{i-2},\forall n\ge3$。 ## 输入格式 第一行输入一个正整数 $t$ 表示询问组数。 接下来 $t$ 行,每行两个正整数 $n,m$ 表示一次询问。 ## 输出格式 每次询问输出一行一个整数表示答案。 ## 输入输出样例 #1 ### 输入 #1 ``` 2 1 3 2 3 ``` ### 输出 #1 ``` 2 32 ``` ## 说明/提示 #### 样例解释 对于第一组询问,有答案为 $f_1f_2f_3=1\times1\times2=2$。 对于第二组询问,当 $a_1,a_2\in\{1,2\}$ 时 $\operatorname{lcm}(f_{a_1},f_{a_2})=1$,否则 $\operatorname{lcm}(f_{a_1},f_{a_2})=2$。故答案为 $2^5=32$。 #### 数据范围与限制 **本题采用捆绑测试,各 Subtask 的限制与分值如下。** | Subtask No. | $t\le$ | $n\le$ | $m\le$ | 分值 | | :-: | :-: | :-: | :-: | :-: | | $1$ | $1$ | $2$ | $2 \times 10^3$ | $13$ | | $2$ | $5$ | $2 \times 10^5$ | $2 \times 10^5$ | $24$ | | $3$ | $5$ | $2 \times 10^7$ | $2 \times 10^7$ | $36$ | | $4$ | $300$ | $2 \times 10^{17}$ | $2 \times 10^7$ | $27$ | 对于所有数据,满足 $1 \le t \le 300, 1 \le n \le 2 \times 10^{17}, 1 \le m \le 2 \times 10^7$。 #include<bits/stdc++.h> #define md 37426667 #define int unsigned long long using namespace std; inline int in() { int k=0,f=1; char c=getchar(); while(c<'0'||c>'9') { if(c=='-') f=-1; c=getchar(); } while(c>='0'&&c<='9') k=k*10+c-'0',c=getchar(); return k*f; } inline int out(int a) { if(a<0) putchar('-'),a=-a; if(a<10) putchar(a+'0'); else out(a/10),putchar(a%10+'0'); return 0; } inline int gcd(int a,int b) { while(b){ int t=b; b=a%b; a=t; } return a; } int lcm(int a,int b) { return (a/gcd(a,b))*b%md; } int fib[20000005]; main() { int t=in(); fib[1]=fib[2]=1; for(int i=3; i<=20000000;i++) fib[i]=(fib[i-1]+fib[i-2])%md; while(t--) { int n=in(),m=in(); int ans=1; if(n==1) for(int i=1; i<=m; i++) ans=(ans*fib[i])%md; else if(n==2) { for(int xx=1; xx<=m; xx++) { for(int yy=1; yy<=m; yy++) { ans=(ans*lcm(fib[xx],fib[yy]))%md; } } } out(ans%md); } }
03-16
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值