题目描述:
给出长度为的序列,选出最少的数(非空)使得它们的为
,无解输出
题目分析:
以内质因子最多的数只有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");
}