HDU-1796 How many integers can you find 容斥原理,细节
HDU-1796 How many integers can you find 容斥原理,细节
题意
给定一个\(N\) 和一个大小为\(M\) 的集合,集合元素为非负整数 ,求\([1,n)\) 内是集合里任意一个数的倍数的数字个数
\[n \leq 2^{31},m \leq 10
\]
分析
因为要直接算\(1-n\) 中多少个数字是某个数的倍数是比较好算的,现在只不过是多个数,看到数据范围小于等于10应该比较好想到容斥
\[ans = \sum f(a_i) - \sum f(lcm(a_i,a_j)) + \sum f(lcm(a_i,a_j,a_k))....
\]
然后二进制枚举就完事了
注意点:范围是\([1,n)\) 所以是\((n - 1) / res\) 。 题目只说了非负整数 ,所以如果出现\(0\) 就麻烦了,干脆不读入
代码
vector<int> a;
int main() {
int n, m;
while (~scanf("%d%d", &n, &m)) {
a.clear();
int ans = 0;
for (int i = 0; i < m; i++) {
int x = readint();
if(x) a.push_back(x);
}
m = a.size();
for (int i = 1; i < (1 << m); i++) {
int res = 1;
int byte = 0;
for (int j = 0; j < m; j++) {
if ((1 << j) & i) byte++, res = Lcm(res, a[j]);
}
if (byte & 1) ans += (n - 1) / res;
else ans -= (n - 1) / res;
}
Put(ans);
puts("");
}
}