能被整除的数
能被整除的数
给定一个整数 $n$ 和 $m$ 个不同的质数 $p_1,p_2, \ldots ,p_m$。
请你求出 $1 \sim n$ 中能被 $p_1,p_2, \ldots ,p_m$ 中的至少一个数整除的整数有多少个。
输入格式
第一行包含整数 $n$ 和 $m$。
第二行包含 $m$ 个质数。
输出格式
输出一个整数,表示满足条件的整数的个数。
数据范围
$1 \leq m \leq 16$,
$1 \leq n, p_i \leq {10}^9$
输入样例:
10 2 2 3
输出样例:
7
解题思路
容斥原理。
定义$S_{p_{i}}$表示$1 \sim n$中能被$p_i$整除的数的集合。因此答案就是$$\left| \bigcup\limits_{1 \leq i \leq m} {S_{p_{i}}} \right| = \sum\limits_{1 \leq i \leq m} {\left| S_{p_{i}} \right|} - \sum\limits_{1 \leq {i<j} \leq m} {\left| S_{p_{i}} \cap S_{p_{j}} \right|} + \sum\limits_{1 \leq {i<j<k} \leq m} {\left| S_{p_{i}} \cap S_{p_{j}} \cap S_{p_{k}} \right|} - \dots + {\left( -1 \right)}^{m-1}\left| \bigcap\limits_{1 \leq i \leq m} {S_{p_{i}}} \right|$$
其中 $\left| \bigcap\limits_{1 \leq i \leq k} {S_{p_{i}}} \right|$ 表示$n$中能被$\prod\limits_{i=1}^{k}{p_i}$整除的数的个数,即$$\displaylines {\left| \bigcap\limits_{1 \leq i \leq k} {S_{p_{i}}} \right| = \left\lfloor \dfrac{n}{\prod_{i=1}^{k}{p_i}} \right\rfloor} $$
通过二进制枚举来实现容斥原理的计算过程,时间复杂度为$O(m \cdot 2^m)$。
AC代码如下:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int N = 20; 5 6 int p[N]; 7 8 int main() { 9 int n, m; 10 scanf("%d %d", &n, &m); 11 for (int i = 0; i < m; i++) { 12 scanf("%d", p + i); 13 } 14 int ret = 0; 15 for (int i = 1; i < 1 << m; i++) { 16 int cnt = 0, s = n; 17 for (int j = 0; j < m; j++) { 18 if (i >> j & 1) { 19 cnt++; 20 s /= p[j]; 21 } 22 } 23 if (~cnt & 1) s *= -1; 24 ret += s; 25 } 26 printf("%d", ret); 27 28 return 0; 29 }
参考资料
AcWing 890. 能被整除的数:https://www.acwing.com/video/311/
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/17120794.html