#min-max容斥#51nod 1355 斐波那契的最小公倍数

题目

对于 \(n\leq 50000,a_i\leq 10^6\),求 \(\large lcm(fib(a_1),fib(a_2),\dots,fib(a_{n-1}),fib(a_n))\)


分析

可以发现最小公倍数实际上是取所有质因子幂次的最大值,
然而最大公约数更好求,考虑min-max容斥,也就是

\[\large lcm(S)=\prod_{T\sube 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_{T\sube S}g(T)\),则

\[\large g(S)=\frac{fib(S)}{\prod_{T \subsetneqq S}g(T)} \]

把原来的 \(fib\) 消掉就是

\[\large lcm(S)=\prod g(d)^{\sum_{T\sube 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);
}
posted @ 2021-11-05 09:57  lemondinosaur  阅读(22)  评论(0编辑  收藏  举报