【LOJ #6102】「2017 山東二輪集訓 Day1」第三題(莫比烏斯反演 / min-max容斥)

傳送門

原題
上次沒寫題解這次補一下得了

首先由gcd(fi,fj)=fgcd(i,j)gcd(f_i,f_j)=f_{gcd(i,j)}
首先證明gcd(fi,fi1)=1gcd(f_i,f_{i-1})=1
然後fi+j=fi1fj+fifj+1f_{i+j}=f_{i-1}f_j+f_if_{j+1}
用歸納法可以證明
然後就可以證明gcd(fn+m,fm)=gcd(fn,fm)gcd(f_{n+m},f_m)=gcd(f_n,f_m)
然後就完了

考慮lcmlcm對指數取maxmax
minmaxmin-max容斥得
lcmfT=STfgcd(s)1T+1lcm{f_T}=\prod_{S\subseteq T}f_{gcd(s)}^{-1^{|T|+1}}
考慮設一個gg滿足fn=dngdf_n=\prod_{d|n}g_d
那麼有gn=fndn,dngd1g_n=f_n\prod_{d|n,d\not=n}g_d^{-1}dnfdμ(nd)\prod_{d|n}f_d^{\mu(\frac nd )}

那麼原式=ST(dgcd(S)gd)1T+1=dg(d)TS,T,dgcd(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}}
考慮指數若存在kk個數有dd這個因子
k=0k=0無貢獻
否則=i=1k(ki)(1)i+1=1=\sum_{i=1}^k{k\choose i}(-1)^{i+1}=1
於是每次倍數即可

複雜度O(nlogn)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;
}
發佈了579 篇原創文章 · 獲贊 193 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章