能被整除的数

能被整除的数

给定一个整数 $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/

posted @ 2023-02-14 20:29  onlyblues  阅读(44)  评论(0编辑  收藏  举报
Web Analytics