数论——集合中的质数(容斥原理)
题目描述
给出一个集合和一个数m。
集合里面有n个质数。
请你求出从 1 到 m 的所有数中,至少能被集合中的一个数整除的数的个数。
输入描述
第一行两个正整数 n 和 m 。
第二行n个正整数,分别为集合中的质数。
输出描述
输出一个整数,表示符合要求的正整数的个数。
示例
输入
3 37
5 7 13
输出
13
备注
对于 100% 的数据,有 n <= 20,m 为有符号 64 位正整数,集合内质数 <= 1000000000
分析
根据容斥原理:
假设集合中有三个素数,其分别为 a1,a2,a3 则答案为:
m/a1 + m/a2 + m/a3 - m/(a1 * a2) - m/(a1 * a3) - m/(a2 * a3) + m/(a1 * a2 * a3)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
ll n,m,ans=0,f[30];
cin>>n>>m;
for(int i=0;i<n;i++){
cin>>f[i];
}
for(int i=1;i<(1<<n);i++){ // 枚举集合中全部的非空子集
ll s=m,cnt=0; // s 用来表示满足条件的数的个数,cnt 用来表示所取的数的个数
for(int j=0;j<n;j++){
if((i>>j)&1){ // 若该位为 1,就取
cnt++;
s/=f[j];
}
}
if(cnt&1){ // 根据容斥原理,若 cnt 为奇数,则相加
ans+=s;
}
else{
ans-=s; // 若 cnt 为偶数,则相减
}
}
cout<<ans<<endl;
return 0;
}