题意:
【51nod1355】斐波那契的最小公倍数(min - max容斥)(容斥)(反演)_取模 个数 【51nod1355】斐波那契的最小公倍数(min - max容斥)(容斥)(反演)_取模_02,求 【51nod1355】斐波那契的最小公倍数(min - max容斥)(容斥)(反演)_斐波那契数列_03【51nod1355】斐波那契的最小公倍数(min - max容斥)(容斥)(反演)_斐波那契数列_04,对 【51nod1355】斐波那契的最小公倍数(min - max容斥)(容斥)(反演)_斐波那契数列_05 取模


首先我们知道斐波那契数列的一些性质

  1. 【51nod1355】斐波那契的最小公倍数(min - max容斥)(容斥)(反演)_斐波那契数列_06
  2. 【51nod1355】斐波那契的最小公倍数(min - max容斥)(容斥)(反演)_斐波那契数列_07
  3. 【51nod1355】斐波那契的最小公倍数(min - max容斥)(容斥)(反演)_取模_08

第 2 个可以用归纳法证明,不是很难

我们考虑把求 【51nod1355】斐波那契的最小公倍数(min - max容斥)(容斥)(反演)_斐波那契数列_09 变成 【51nod1355】斐波那契的最小公倍数(min - max容斥)(容斥)(反演)_取模_10【51nod1355】斐波那契的最小公倍数(min - max容斥)(容斥)(反演)_斐波那契数列_11 容斥
【51nod1355】斐波那契的最小公倍数(min - max容斥)(容斥)(反演)_斐波那契数列_12 表示质因子次数,【51nod1355】斐波那契的最小公倍数(min - max容斥)(容斥)(反演)_取模_13【51nod1355】斐波那契的最小公倍数(min - max容斥)(容斥)(反演)_斐波那契数列_12 的集合

【51nod1355】斐波那契的最小公倍数(min - max容斥)(容斥)(反演)_取模_15
【51nod1355】斐波那契的最小公倍数(min - max容斥)(容斥)(反演)_取模_16
【51nod1355】斐波那契的最小公倍数(min - max容斥)(容斥)(反演)_取模_17

发现不是很好搞,考虑反演,令 【51nod1355】斐波那契的最小公倍数(min - max容斥)(容斥)(反演)_i++_18

那么有 【51nod1355】斐波那契的最小公倍数(min - max容斥)(容斥)(反演)_斐波那契数列_19
不妨另为 【51nod1355】斐波那契的最小公倍数(min - max容斥)(容斥)(反演)_取模_10 倍数且在 【51nod1355】斐波那契的最小公倍数(min - max容斥)(容斥)(反演)_取模_13 的集合为 【51nod1355】斐波那契的最小公倍数(min - max容斥)(容斥)(反演)_i++_22,那么

【51nod1355】斐波那契的最小公倍数(min - max容斥)(容斥)(反演)_斐波那契数列_23

倒过来调和级数求即可

#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;
}