题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1796
题目大意:给定一个N和一个有M个数的集合S,求出小于N的数中有多少能被集合S中的数整除.
思路:基本的容斥原理。设Xi为小于N的数中能整除集合中i个数的个数,则Xans = X1 - X2 + X3 - X4 + ……
需要注意的就是在求能整除多个数的个数的时候,
应该用N除以它们的最小公倍数,而不是他们的乘积。
#include
#include
using namespace std;
vector p;
long long gcd(long long a, long long b){
return b?gcd(b, a % b):a;
}
long long lcm(long long a, long long b){
return a * b / gcd(a, b);
}
long long solve(int n){
long long res = 0;
for (int msk = 1; msk < (1 << p.size()); msk ++){
int mult = 1, bit = 0;
for (int i = 0; i < p.size(); i ++){
if (msk & (1 << i)){
bit ++;
mult = lcm(mult, p[i]);
}
}
int cur = (n - 1) / mult;
if (bit % 2 == 1){
res += cur;
}
else{
res -= cur;
}
}
return res;
}
int main(){
int n,m;
while(cin>>n>>m){
p.clear();
for (int i = 0; i < m; i ++){
int x;
cin>>x;
if (x != 0)
p.push_back(x);
}
cout<