題目描述:
給出長度爲的序列,選出最少的數(非空)使得它們的爲
,無解輸出
題目分析:
以內質因子最多的數只有6個,而如果有解,考慮其中質因子最少的數,其餘每個數一定囊括了一個不在中的質因子,且各自囊括的那個質因子不同,(相當於不斷去掉gcd的因子)。也就是說答案最多是的質因子個數+1,也就是。
這張例子截自洛谷的題解:
那麼枚舉答案的個數,求出選出個數組成的方案,只需要求出選出個數組成爲的倍數的方案,我們就可以通過容斥或莫比烏斯反演求出。
而 ,表示中爲的倍數的數的個數。
由莫比烏斯反演有:
由容斥有:
於是就做完了,複雜度
Code:
#include<bits/stdc++.h>
#define maxn 300005
using namespace std;
const int mod = 998244353;
int n,a[maxn],mx,f[maxn],fac[maxn],inv[maxn];
int C(int n,int m){return n<m?0:1ll*fac[n]*inv[m]%mod*inv[n-m]%mod;}
int main()
{
scanf("%d",&n);
for(int i=1,x;i<=n;i++) scanf("%d",&x),a[x]++,mx=max(mx,x);
fac[0]=fac[1]=inv[0]=inv[1]=1;
for(int i=2;i<=n;i++) fac[i]=1ll*fac[i-1]*i%mod,inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
for(int i=2;i<=n;i++) inv[i]=1ll*inv[i]*inv[i-1]%mod;
for(int i=1;i<=mx;i++)
for(int j=i+i;j<=mx;j+=i) a[i]+=a[j];
for(int k=1;k<=7;k++){
for(int i=mx;i>=1;i--){
f[i]=C(a[i],k);
for(int j=i+i;j<=mx;j+=i) f[i]=(f[i]-f[j])%mod;
}
if(f[1]) return printf("%d\n",k),0;
}
puts("-1");
}