题意:
给
m
m
m 个数
a
i
a_i
ai,求
l
c
m
(
f
i
b
(
a
i
)
)
lcm(fib(a_i))
lcm(fib(ai)),
m
≤
4
e
5
,
a
i
≤
1
e
6
m\le 4e5, a_i\le 1e6
m≤4e5,ai≤1e6,对
1
e
9
+
7
1e9+7
1e9+7 取模
首先我们知道斐波那契数列的一些性质
- g c d ( f i b i , f i b i − 1 ) = 1 gcd(fib_i,fib_{i-1})=1 gcd(fibi,fibi−1)=1
- f n + m = f m + 1 ∗ f n + f m ∗ f n − 1 f_{n+m}=f_{m+1}*f_n+f_m*f_{n-1} fn+m=fm+1∗fn+fm∗fn−1
- g c d ( f n + m , f n ) = g c d ( f m + 1 ∗ f n + f m ∗ f n − 1 , f n ) = g c d ( f m , f n ) ⇒ g c d ( f n , f m ) = f g c d ( n , m ) gcd(f_{n+m},f_n)=gcd(f_{m+1}*f_n+f_m*f_{n-1},f_n)=gcd(f_m,f_n)\Rightarrow gcd(f_n,f_m)=f_{gcd(n,m)} gcd(fn+m,fn)=gcd(fm+1∗fn+fm∗fn−1,fn)=gcd(fm,fn)⇒gcd(fn,fm)=fgcd(n,m)
第 2 个可以用归纳法证明,不是很难
我们考虑把求
l
c
m
lcm
lcm 变成
g
c
d
gcd
gcd,
m
i
n
m
a
x
min\ max
min max 容斥
令
m
i
m_i
mi 表示质因子次数,
S
S
S 为
m
i
m_i
mi 的集合
l
c
m
(
f
i
b
(
a
i
)
)
=
∏
p
i
m
a
x
(
S
)
=
∏
p
i
∑
T
⊂
S
(
−
1
)
∣
T
∣
+
1
m
i
n
(
T
)
lcm(fib(a_i))=\prod p_i^{max(S)}=\prod p_i^{\sum_{T\subset S}(-1)^{|T|+1}min(T)}
lcm(fib(ai))=∏pimax(S)=∏pi∑T⊂S(−1)∣T∣+1min(T)
=
∏
T
⊂
S
∏
i
p
i
(
−
1
)
∣
T
∣
+
1
∗
m
i
n
(
T
)
=\prod_{T\subset S} \prod_ip_i^{(-1)^{|T|+1}*min(T)}
=∏T⊂S∏ipi(−1)∣T∣+1∗min(T)
=
∏
T
⊂
S
g
c
d
(
T
)
(
−
1
)
∣
T
∣
+
1
=\prod_{T\subset S}gcd(T)^{(-1)^{|T|+1}}
=∏T⊂Sgcd(T)(−1)∣T∣+1
发现不是很好搞,考虑反演,令 f ( n ) = ∏ T ⊂ S , g c d ( T ) = n f i b ( n ) ( − 1 ) ∣ T ∣ + 1 , g ( n ) = ∏ n ∣ d f ( d ) f(n)=\prod_{T\subset S,gcd(T)=n}fib(n)^{(-1)^{|T|+1}},g(n)=\prod_{n|d}f(d) f(n)=∏T⊂S,gcd(T)=nfib(n)(−1)∣T∣+1,g(n)=∏n∣df(d)
那么有
g
(
n
)
=
∏
T
⊂
S
,
g
c
d
(
T
)
∣
n
f
i
b
(
n
)
(
−
1
)
∣
T
∣
+
1
g(n)=\prod_{T\subset S,gcd(T)|n}fib(n)^{(-1)^{|T|+1}}
g(n)=∏T⊂S,gcd(T)∣nfib(n)(−1)∣T∣+1
不妨另为
g
c
d
gcd
gcd 倍数且在
S
S
S 的集合为
A
A
A,那么
g ( n ) = ∏ T ⊂ A f i b ( n ) ( − 1 ) ∣ T ∣ + 1 = f i b ( n ) ( A ≠ ∅ ) g(n)=\prod_{T\subset A}fib(n)^{(-1)^{|T|+1}}=fib(n)(A\ne\empty) g(n)=∏T⊂Afib(n)(−1)∣T∣+1=fib(n)(A=∅)
f ( n ) = g ( n ) ∗ ( ∏ n ∣ d , d ! = n f ( d ) ) − 1 f(n)=g(n)*(\prod_{n|d,d!=n} f(d))^{-1} f(n)=g(n)∗(∏n∣d,d!=nf(d))−1
倒过来调和级数求即可
#include<bits/stdc++.h>
#define cs const
using namespace std;
cs int N = 1e6 + 5;
cs int Mod = 1e9 + 7;
int add(int a, int b){ return a + b >= Mod ? a + b - Mod : a + b; }
int mul(int a, int b){ return 1ll * a * b % Mod; }
int ksm(int a, int b){ int ans=1; for(;b;b>>=1,a=mul(a,a)) if(b&1) ans=mul(ans,a); return ans; }
int n, a[N], g[N], f[N], mx;
int main(){
cin >> n;
for(int i = 1, x; i <= n; i++){
scanf("%d", &x); a[x] = 1;
mx = max(mx, x);
}
f[1] = 1;
for(int i = 2; i <= mx; i++) f[i] = add(f[i-1], f[i-2]);
for(int i = mx; i >= 1; i--)
for(int j = i+i; j <= mx; j += i) a[i] |= a[j];
for(int i = 1; i <= mx; i++) g[i] = f[i];
for(int i = 1; i <= mx; i++){
int iv = ksm(g[i], Mod-2);
for(int j = i+i; j <= mx; j += i) g[j] = mul(g[j], iv);
}
int ans = 1;
for(int i = 1; i <= mx; i++) if(a[i]) ans = mul(ans, g[i]);
cout << ans; return 0;
}