题目
对于 (nleq 50000,a_ileq 10^6),求 (large lcm(fib(a_1),fib(a_2),dots,fib(a_{n-1}),fib(a_n)))
分析
可以发现最小公倍数实际上是取所有质因子幂次的最大值,
然而最大公约数更好求,考虑min-max容斥,也就是
[large lcm(S)=prod_{Tsube S} gcd(T)^{(-1)^{|T|-1}}
]
由于 (gcd(fib(a_1),fib(a_2),dots,fib(a_{n-1}),fib(a_n))=fib(gcd(a_1,a_2,dots,a_{n-1},a_n))),
那么
[large lcm(S)=prod_{T'sube S} fib(gcd(T'))^{(-1)^{|T'|-1}}
]
考虑枚举最大公约数,也就是说所有数都要是其倍数,但是这样也很难处理,
那么设 (fib(S)=prod_{Tsube S}g(T)),则
[large g(S)=frac{fib(S)}{prod_{T subsetneqq S}g(T)}
]
把原来的 (fib) 消掉就是
[large lcm(S)=prod g(d)^{sum_{Tsube S,d|gcd(T)}{(-1)^{|T|-1}}}
]
设 (n) 个数为 (d) 的倍数,那么指数就是
[sum_{i=1}^n(-1)^{i-1}C(n,i)=1-sum_{i=0}^n(-1)^iC(n,i)=1-(1-1)^n=[n>0]
]
那也就是
[large lcm(S)=prod_{exist d|a_i} g(d)
]
代码
#include <cstdio>
#include <cctype>
using namespace std;
const int N=1000011,mod=1000000007;
int n,f[N],v[N],ans=1,mx;
int iut(){
int ans=0; char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
int ksm(int x,int y){
int ans=1;
for (;y;y>>=1,x=1ll*x*x%mod)
if (y&1) ans=1ll*ans*x%mod;
return ans;
}
int main(){
n=iut(),f[1]=1;
for (int i=1;i<=n;++i){
int x=iut(); v[x]=1;
mx=mx>x?mx:x;
}
for (int i=2;i<=mx;++i) f[i]=(f[i-1]+f[i-2])%mod;
for (int i=1;i<=mx;++i){
int now=ksm(f[i],mod-2);
for (int j=i+i;j<=mx;j+=i)
f[j]=1ll*f[j]*now%mod;
}
for (int i=1;i<=mx;++i)
for (int j=i;j<=mx;j+=i) if (v[j])
{ans=1ll*ans*f[i]%mod; break;}
return !printf("%d",ans);
}