您的位置:首页 > 教育 > 锐评 > 东莞网站优化费用_个人能做网站吗_跨境电商平台排行榜前十名_淘宝搜索关键词排名

东莞网站优化费用_个人能做网站吗_跨境电商平台排行榜前十名_淘宝搜索关键词排名

2025/2/24 14:03:44 来源:https://blog.csdn.net/m0_62112384/article/details/143082951  浏览:    关键词:东莞网站优化费用_个人能做网站吗_跨境电商平台排行榜前十名_淘宝搜索关键词排名
东莞网站优化费用_个人能做网站吗_跨境电商平台排行榜前十名_淘宝搜索关键词排名

题目

图源ACWING

解题思路

什么是容斥原理
在这里插入图片描述
具体到题目中
S1代表1到n中能被质数p1整除的数的集合,而|S1|代表1~n中能被质数p1整除的数的数量;

则题目所求结果:
res = | S1 U S2 U S3 … U Sm | = |S1| + |S2| + |S3| + … + |Sm| (C(m, 1)个数) - (|S1 ∩ S2| + |S1 ∩ S3| + …) (C(m, 2)个数) + … + (-1)n-1(S1∩S2∩S3…∩Sm) (C(m, m) 个数)

同时C(m, 0) + C(m ,1) + C(m, 2) + C(m , 3) + … C(m, m) = 2m(相当于一个球袋中拿走任意数量的球的方案量, 即每个球都只有拿走与不拿走两个选项,总方案量就是2m)

所以,总循环次数就是2m - 1,即可得到答案res;

具体实现方法
图源https://www.acwing.com/solution/content/29702/

代码实现

#include <iostream>
#include <algorithm>using namespace std;typedef long long LL;const int N = 20;int p[N];int main()
{int n, m;cin >> n >> m;// 用p数组存储m个质数for (int i = 0; i < m; i ++ ) cin >> p[i];int res = 0;// 每一个i代表一种可能的取法,最外层的循环遍历置2的m次方后,可以取完所有的取法// 从1开始枚举,枚举到1 << m(左移m位。左移一位相当于乘2,右移一位相当于除2),即2的m次方;for (int i = 1; i < 1 << m ; i ++ )//等同于i < 2^m^{// t代表当前所有质数的乘积,s代表什么当前选法包含几个集合int t = 1, s = 0;// 枚举m个质数,依次计算容斥原理的公式for (int j = 0; j < m; j ++ ){// i右移j位与上1,即如果当前位是1的话//>>的优先级大于&,所以是先>>再&!if (i >> j & 1){if ((LL)t * p[j] > n)//主要原因是为了防止爆long long,导致出现错误答案!!!{t = -1;break; // break的作用域是跳出整个循环}// 将该质数乘到t中t *= p[j];// s表示当前选法中有多少个集合s ++ ;}}// 带入公式求解一个S// 如果t不等于-1(-1是给定的flag值)if (t != -1){//根据公式,如果s是偶数要减去,是奇数要加上if (s % 2) res += n / t;else res -= n / t;}}cout << res << endl;return 0;
}

具体代码块分析

假设m = 4的情况下:

 // 每一个i代表一种可能的取法,最外层的循环遍历置2的m次方后,可以取完所有的取法for (int i = 1; i < 1 << m ; i ++ )//等同于i < 2^m^

这段代码等同于:i = 0001; i < 10000; i ++ (二进制);
而不同的i代表选择了不同的集合:
比如i = 0101时, 选择了S1和S3这两个集合。
继续带入下面的代码:

        for (int j = 0; j < m; j ++ ){// i右移j位与上1,即如果当前位是1的话//>>的优先级大于&,所以是先>>再&!if (i >> j & 1){if ((LL)t * p[j] > n)//主要原因是为了防止爆long long 的数据范围,导致出现错误!!!{t = -1;break;}// 将该质数乘到t中t *= p[j];// s表示当前选法中有多少个集合s ++ ;}}// 带入公式求解一个S// 如果t不等于-1(-1是给定的flag值)if (t != -1){//根据公式,如果s是偶数要减去,是奇数要加上if (s % 2) res += n / t;else res -= n / t;}

实际上计算的是|S1∩S3|的值;

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com