一个小于三十万的数最多只有七个不同的质因数,所以最多七个数
考虑取n个数使gcd为一是否有解,显然跟点分治一样,两个包含因子x的数的gcd可能是x及其倍数,于是容斥
每个gcd所存在的解数为所有是他倍数的数的数量中任取n个,接着减去所有gcd会是他倍数的情况
复杂度是调和级数,nlogn
代码如下:
#include<bits/stdc++.h>
#define mod 1000000007
using namespace std;
int a[300010],cnt[300010],n;
long long dp[300010];
long long fac[300010],inv[300010];
long long kasumi(long long a,long long b)
{
long long ans=1;
while(b)
{
if(b&1) ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
long long c(long long x,long long y)
{
if(y>x) return 0;
return fac[x]*inv[x-y]%mod*inv[y]%mod;
}
int main()
{
fac[0]=1;
fac[1]=1;
for(int i=2;i<=300000;i++)
{
fac[i]=fac[i-1]*i%mod;
}
inv[300000]=kasumi(fac[300000],mod-2);
for(int i=299999;i>=1;i--)
{
inv[i]=inv[i+1]*(i+1)%mod;
}
inv[0]=1;
scanf("%d",&n);
int tmp;
for(int i=1;i<=n;i++)
{
scanf("%d",&tmp);
a[tmp]++;
}
for(int i=1;i<=300000;i++)
{
tmp=0;
for(int j=i;j<=300000;j+=i)
{
tmp+=a[j];
}
cnt[i]=tmp;
}
for(int t=1;t<=7;t++)
{
memset(dp,0,sizeof(dp));
for(int i=300000;i>=1;i--)
{
dp[i]=c(cnt[i],t);
for(int j=i*2;j<=300000;j+=i)
{
dp[i]=(dp[i]-dp[j]+mod)%mod;
}
}
if(dp[1]>0)
{
printf("%d\n",t);
return 0;
}
}
puts("-1");
}