链接:https://ac.nowcoder.com/acm/problem/14686
来源:牛客网
题目描述
给出一个集合和一个数m。
集合里面有n个质数。
请你求出从 1 到 m 的所有数中,至少能被集合中的一个数整除的数的个数。
输入描述:
第一行两个正整数 n 和 m 。
第二行n个正整数,分别为集合中的质数。
输出描述:
输出一个整数,表示符合要求的正整数的个数。
相关知识
1、容斥原理
通过容斥原理可以得知个数的求解方法:
选择奇数个集合时候前面符号为加,选择偶数个集合时前面符号为减
接下来的问题就是如何表示出选择集合的情况
2、二进制枚举
i表示选择集合的情况,j用于判断是否选择某个集合
i>>j&1表示判断i的二进制数的第j位是不是1
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
int n,i,j;
ll m,p[25],ans=0;
cin>>n>>m;
for(i=0;i<n;i++)
{
cin>>p[i];
}
for(i=1;i<(1<<n); i++)//i来表示选择集合的情况
{
ll t=1; //t表示质数乘积
int s=0; //s表示选择了多少个集合
for(j=0;j<n;j++) //遍历n个集合
{
if (i>>j&1) //如果有选择这个集合
{
if (t*p[j]>m)
{ //选择集合对应质数乘积超过n
//这种情况交集为空
t=-1;
break;
}
t*=p[j]; //计算质数乘积
s++; //选择的集合数+1
}
}
if (t!=-1)//交集不为空
{
if (s%2==0) ans-=m/t; //如果是偶数就加
else ans+=m/t; //如果是奇数就减
}
}
cout<<ans<<endl;
return 0;
}