【LOJ #6102】「2017 山东二轮集训 Day1」第三题(莫比乌斯反演 / min-max容斥)

传送门

原题
上次没写题解这次补一下得了

首先由 g c d ( f i , f j ) = f g c d ( i , j ) gcd(f_i,f_j)=f_{gcd(i,j)}
首先证明 g c d ( f i , f i 1 ) = 1 gcd(f_i,f_{i-1})=1
然后 f i + j = f i 1 f j + f i f j + 1 f_{i+j}=f_{i-1}f_j+f_if_{j+1}
用归纳法可以证明
然后就可以证明 g c d ( f n + m , f m ) = g c d ( f n , f m ) gcd(f_{n+m},f_m)=gcd(f_n,f_m)
然后就完了

考虑 l c m lcm 对指数取 m a x max
m i n m a x min-max 容斥得
l c m f T = S T f g c d ( s ) 1 T + 1 lcm{f_T}=\prod_{S\subseteq T}f_{gcd(s)}^{-1^{|T|+1}}
考虑设一个 g g 满足 f n = d n g d f_n=\prod_{d|n}g_d
那么有 g n = f n d n , d n g d 1 g_n=f_n\prod_{d|n,d\not=n}g_d^{-1} d n f d μ ( n d ) \prod_{d|n}f_d^{\mu(\frac nd )}

那么原式 = S T ( d g c d ( S ) g d ) 1 T + 1 = d g ( d ) T S , T , d g c d ( S ) ( 1 ) T + 1 =\prod_{S\subseteq T}(\prod_{d|gcd(S)}g_d)^{-1^{|T+1|}}=\prod_{d}g(d)^{\sum_{T\subseteq S,T\not=\empty,d|gcd(S)}(-1)^{|T|+1}}
考虑指数若存在 k k 个数有 d d 这个因子
k = 0 k=0 无贡献
否则 = i = 1 k ( k i ) ( 1 ) i + 1 = 1 =\sum_{i=1}^k{k\choose i}(-1)^{i+1}=1
于是每次倍数即可

复杂度 O ( n l o g n ) O(nlogn)

#include<bits/stdc++.h>
using namespace std;
const int RLEN=1<<20|1;
inline char gc(){
    static char ibuf[RLEN],*ib,*ob;
    (ob==ib)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
    return (ob==ib)?EOF:*ib++;
}
inline int read(){
    char ch=gc();
    int res=0,f=1;
    while(!isdigit(ch))f^=ch=='-',ch=gc();
    while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
    return f?res:-res;
}
#define ll long long
#define re register
#define pii pair<int,int>
#define fi first
#define se second
#define pb push_back
#define cs const
#define bg begin
#define poly vector<int>  
cs int mod=1e9+7;
inline int add(int a,int b){return (a+=b)>=mod?a-mod:a;}
inline int dec(int a,int b){return (a-=b)<0?a+mod:a;}
inline int mul(int a,int b){return 1ll*a*b%mod;}
inline void Add(int &a,int b){(a+=b)>=mod?a-=mod:0;}
inline void Dec(int &a,int b){(a-=b)<0?a+=mod:0;}
inline void Mul(int &a,int b){a=1ll*a*b%mod;}
inline int ksm(int a,int b,int res=1){for(;b;b>>=1,Mul(a,a))(b&1)&&(Mul(res,a),1);return res;}
inline int Inv(int x){return ksm(x,mod-2);}
inline void chemx(int &a,int b){a<b?a=b:0;}
inline void chemn(int &a,int b){a>b?a=b:0;}
cs int N=1000005;
int n,a[N],mx;
bitset<N> vis;
int pr[N],tot,mu[N];
int f[N],g[N];
inline void init(cs int len=N-5){
	mu[1]=1;
	for(int i=2;i<=len;i++){
		if(!vis[i])pr[++tot]=i,mu[i]=-1;
		for(int j=1;j<=tot&&pr[j]*i<=len;j++){
			vis[i*pr[j]]=1;
			if(i%pr[j]==0)break;
			mu[i*pr[j]]=-mu[i];
		}
	}vis.reset();
}
int main(){
	#ifdef Stargazer
	freopen("lx.in","r",stdin);
	#endif
	init(),n=read();
	for(int i=1;i<=n;i++)a[i]=read(),chemx(mx,a[i]),vis[a[i]]=1;
	f[1]=f[2]=g[1]=g[2]=1;
	for(int i=3;i<=mx;i++)f[i]=add(f[i-1],f[i-2]),g[i]=1;
	for(int i=1;i<=mx;i++)
	for(int j=1,iv=Inv(f[i]);j*i<=mx;j++)
	if(mu[j])Mul(g[i*j],mu[j]==1?f[i]:iv);
	int res=1;
	for(int i=1;i<=mx;i++)
	for(int j=i;j<=mx;j+=i)
	if(vis[j]){Mul(res,g[i]);break;}
	cout<<res;
}
发布了589 篇原创文章 · 获赞 194 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_42555009/article/details/104399422