目录
- 1 基础知识
- 2 模板
- 3 工程化
1 基础知识
题目描述:给定整数n和m个不同的质数,p1,p2,…pm,求1~n中能被这m个质数中至少一个质数整除的数有多少个。其中n和 p i p_i pi在 1 0 9 10^9 109以内,而m在16以内。
容斥原理:
有两个集合 A A A和 B B B,求总和 ∣ A ∪ B ∣ |A\cup B| ∣A∪B∣,答案为
∣ A ∪ B ∣ = ∣ A ∣ + ∣ B ∣ − ∣ A ∩ B ∣ |A\cup B|=|A| +|B| - |A\cap B| ∣A∪B∣=∣A∣+∣B∣−∣A∩B∣
有三个集合 A A A、 B B B和 C C C,求总和 ∣ A ∪ B ∪ C ∣ |A\cup B\cup C| ∣A∪B∪C∣,答案为
∣ A ∪ B ∪ C ∣ = ∣ A ∣ + ∣ B ∣ + ∣ C ∣ − ∣ A ∩ B ∣ − ∣ A ∩ C ∣ − ∣ B ∩ C ∣ + ∣ A ∩ B ∩ C ∣ |A\cup B \cup C|=|A|+|B|+|C|-|A\cap B|-|A\cap C|-|B\cap C|+|A\cap B \cap C| ∣A∪B∪C∣=∣A∣+∣B∣+∣C∣−∣A∩B∣−∣A∩C∣−∣B∩C∣+∣A∩B∩C∣
进一步抽象,
某个类有 n n n中不同的属性,记为 P i P_i Pi(其中 i = 1 , 2 ⋯ n i=1,2\cdots n i=1,2⋯n),拥有属性 P i P_i Pi的对象构成集合 S i S_i Si,那么对象总和为,
∣ ∪ i = 1 n S i ∣ = ∑ i ∣ S i ∣ − ∑ i < j ∣ S i ∩ S j ∣ + ∑ i < j < k ∣ S i ∩ S j ∩ S k ∣ − ⋯ + ( − 1 ) n − 1 ∣ S 1 ∩ S 2 ⋯ ∩ S n ∣ |\cup_{i=1}^{n} S_i|=\sum_{i}|S_i|-\sum_{i<j}|S_i\cap S_j|+\sum_{i<j<k}|S_i\cap S_j \cap S_k| - \cdots +(-1)^{n-1}|S_1\cap S_2 \cdots \cap S_n| ∣∪i=1nSi∣=i∑∣Si∣−i<j∑∣Si∩Sj∣+i<j<k∑∣Si∩Sj∩Sk∣−⋯+(−1)n−1∣S1∩S2⋯∩Sn∣
上式即为容斥原理。
解题思路:用容斥原理进行求解,且利用二进制表示中的1表示第i个质数选不选,以此计算出每一项。
C++代码如下,
#include <iostream>using namespace std;const int N = 20;
int n, m;
int p[N];int main() {cin >> n >> m;for (int i = 0; i < m; ++i) cin >> p[i];int res = 0;for (int i = 1; i < 1 << m; ++i) {int t = 1;int cnt = 0;for (int j = 0; j < m; ++j) {if (i >> j & 1) {cnt += 1;if ((long long)t * p[j] > n) {t = -1;break;}t = (long long)t * p[j];}}if (t != -1) {if (cnt % 2 == 1) {res += n / t;} else {res -= n / t;}}}cout << res << endl;return 0;
}
2 模板
暂无。。。
3 工程化
暂无。。。