题意
给
你
n
个
数
,
取
出
一
些
数
使
这
些
数
的
最
大
公
约
数
为
1
,
求
取
出
数
字
的
最
少
个
数
,
不
能
输
出
−
1.
给你n个数,取出一些数使这些数的最大公约数为1,求取出数字的最少个数,不能输出-1.
给你n个数,取出一些数使这些数的最大公约数为1,求取出数字的最少个数,不能输出−1.
数据范围两个
3
×
1
0
5
3\times 10^5
3×105.
秒杀
可以看到当几个质数分别为
a
,
b
,
c
,
d
,
e
,
f
.
.
.
.
.
.
a,b,c,d,e,f......
a,b,c,d,e,f......时,
a
b
c
d
e
,
a
b
c
d
f
,
a
b
c
e
f
,
a
b
d
e
f
,
a
c
d
e
f
,
b
c
d
e
f
abcde,abcdf,abcef,abdef,acdef,bcdef
abcde,abcdf,abcef,abdef,acdef,bcdef能使答案为6.所以由于
2
×
3
×
5
×
7
×
11
×
13
×
17
>
300000
2\times 3\times 5\times 7\times 11\times 13\times17>300000
2×3×5×7×11×13×17>300000,答案最大为7.
接下去从小到大枚举答案判断是否可行.
设当前取
i
i
i个数字,则令
d
p
[
j
]
dp[j]
dp[j]表示取
i
i
i个数字使最大公约数为
j
j
j的方法总数.
再令
c
n
t
[
j
]
cnt[j]
cnt[j]表示
a
a
a数组中能被
j
j
j整除的数字总数,则
d
p
[
j
]
=
C
c
n
t
[
j
]
i
−
∑
k
=
j
×
2
3
×
1
0
5
d
p
[
k
]
(
k
m
o
d
j
=
0
)
dp[j]=C^i_{cnt[j]}-\sum_{k=j\times2}^{3\times10^5}dp[k](k\ mod\ j=0)
dp[j]=Ccnt[j]i−k=j×2∑3×105dp[k](k mod j=0)
仔细思考一下很容易出来.
最后只要看
d
p
[
1
]
dp[1]
dp[1],不为
0
0
0即可说明
i
i
i可行,直接输出.
如果到了
7
7
7还是没有答案,直接输出
−
1
-1
−1就好了.
代码如下.如果
d
p
[
i
]
dp[i]
dp[i]非常大,只要选个大质数取模即可.
#include<bits/stdc++.h> //Ithea Myse Valgulious
/*省略*/
using namespace std;
const int yuzu=3e5,mod=1e9+7;
typedef ll fuko[yuzu|10];
fuko cnt,dp,jic={1},inv={1};
ll kasumi(ll a,ll b=mod-2) {
ll ans=1;
for (;b;b>>=1,a=a*a%mod) if (b&1) ans=ans*a%mod;
return ans;
}
int main() {
int i,n=read(),j,k;
for (i=1;i<=n;++i) ++cnt[read()];
for (i=1;i<=yuzu;++i) jic[i]=jic[i-1]*i%mod;
inv[yuzu]=kasumi(jic[yuzu]);
for (i=yuzu-1;i;--i) inv[i]=inv[i+1]*(i+1)%mod;
/*简单处理阶乘和逆元*/
for (i=1;i<=yuzu;++i) {
for (j=i<<1;j<=yuzu;j+=i)
cnt[i]+=cnt[j];
}
for (i=1;i<=7;++i) {
for (j=yuzu;j;--j) {
dp[j]=cnt[j]<i?0:jic[cnt[j]]*inv[i]%mod*inv[cnt[j]-i]%mod;
for (k=j<<1;k<=yuzu;k+=j) {
dp[j]=(dp[j]-dp[k]+mod)%mod;
}
}
if (dp[1]) return printf("%d\n",i)&0;
}
puts("-1");
}
谢谢大家.