【容斥原理】codeforces 2125 C. Count Good Numbers
题目
https://codeforces.com/problemset/problem/2125/C
题解
此题是容斥原理的典题,先简要介绍容斥原理:
容斥原理的核心思想是:“先全部加起来,再减去多算的,再加回多减的,如此反复,直到得到精确结果”。它用于计算多个集合的并集大小,尤其是在这些集合有重叠时。容斥原理的一般形式为:
\[\left| \bigcup_{i=1}^{n} A_i \right| = \sum_{k=1}^{n} (-1)^{k+1} \sum_{1 \leq i_1 < \dots < i_k \leq n} \left| A_{i_1} \cap \dots \cap A_{i_k} \right|
\]
本题要求的是大小在 \(l\) 和 \(r\) 之间(包括端点)的所有质因子都至少为两位数的数的个数,而一位数的质数有且仅有2 3 5 7四个数,因此只要算出 \(1\) ~ \(r\) 范围内剔除所有质因数包含2 3 5 7的数的个数,再减去\(1\) ~ \(l\) 范围内剔除所有质因数包含2 3 5 7的数的个数,就是答案。
参考代码
int a[N] = {2,3,5,7};//小于 10 的所有质数
ll calc(ll x) {// 计算 x 以内有多少个数的质因子至少都是大于等于 10 的
if (x <= 0) return 0LL;
ll res = x;
for (int i = (1 << 4) - 1; i; -- i) {
int signal = 0;
int product = 1;
for (int j = 0; j < 4; ++ j) {
if (i >> j & 1) {
++ signal;
product *= a[j];
}
}
signal = signal & 1 ? -1 : 1;
res += signal * x / product;
}
return res;
}
void solve() {
ll l, r;
cin >> l >> r;// 输入范围
ll ans = calc(r) - calc(l - 1);// 得到 [l, r] 有多少个数满足质因子至少是两位数及以上
cout << ans << '\n';
}
浙公网安备 33010602011771号