算法提高:组合数学| 容斥原理常见应用

简介: 容斥原理常见的问题如下。(1) 篮球、羽毛球、网球三种运动,至少会一种的有22人,会篮球的有15人,会羽毛球的有17人,会网球的有12人,既会篮球又会羽毛球的有11人,既会羽毛球又会网球的有7人,既会篮球又会网球的有9人,那么三种运动都会的有多少人?(2) 《西游记》《三国演义》《红楼梦》三大名著,至少读过其中一本的有20人,读过《西游记》的有10人,读过《三国演义》的有12人,读过《红楼梦》的有15人,读过《西游记》《三国演义》的有8人,读过《三国演义》《红楼梦》的有9人,读过《西游记》《红楼梦》的有7人。问三本书全都读过的有多少人?

640.jpg

容斥原理常见的问题如下。

(1) 篮球、羽毛球、网球三种运动,至少会一种的有22人,会篮球的有15人,会羽毛球的有17人,会网球的有12人,既会篮球又会羽毛球的有11人,既会羽毛球又会网球的有7人,既会篮球又会网球的有9人,那么三种运动都会的有多少人?

(2) 《西游记》《三国演义》《红楼梦》三大名著,至少读过其中一本的有20人,读过《西游记》的有10人,读过《三国演义》的有12人,读过《红楼梦》的有15人,读过《西游记》《三国演义》的有8人,读过《三国演义》《红楼梦》的有9人,读过《西游记》《红楼梦》的有7人。问三本书全都读过的有多少人?

01、原理概述

容斥原理是一种较常用的计数方法,其基本思想是: 先不考虑重叠的情况,把包含于某内容中的所有对象的数目先计算出来,然后再把计数时重复计算的数目排斥出去,使得计算的结果既无遗漏,又无重复。

容斥原理核心的计数规则可以记为一句话: 奇加偶减。

假设被计数的有A、B、C三类,那么,A、B、C类元素个数总和=A类元素个数+B类元素个数+C类元素个数-既是A又是B的元素个数-既是B又是C的元素个数-既是A又是C的元素个数+既是A又是B且是C的元素个数,即A∪B∪C=A+B+C-A∩B-B∩C-A∩C+A∩B∩C,如图1所示。

640.png


■ 图1容斥定理

当被计数的种类被推到n类时,其统计规则遵循奇加偶减。

容斥定理最常用于求[a,b]区间与n互质的数的个数,该问题可视为求[1,b]区间与n互质的个数减去[1,a-1]区间内与n互质的个数,故可先对n进行因子分解,然后从[1,b]、[1,a-1]区间中减去存在n的因子的个数,再根据容斥定理,奇加偶减,对n的因子的最小公倍数的个数进行处理即可。

02、常见应用

  1. 求[a,b]中与n互素的个数

问题可转换为区间[1,b]中与n互素的数的个数减去区间[1,a-1]中与n互素的数的个数,那么问题就转换为对于n,求1~k中与n互质的数有多少个,因此可以先反着求1~k中与n不互质的数有多少个。

故对n进行因子分解,然后从1~k中减去不能与n整除的数的个数,然后根据容斥定理奇加偶减,最后答案是: 1~b的元素个数减去1~a-1的元素个数再减去1~b中与n不互质的数的个数加上1~a-1中与n互质的数的个数,即b-(a-1)-calculate(b)+calculate(a-1)

bool bprime[N];LI prime[N],cnt,factor[N],num;void isprime() l
//筛选素数
cnt=0;
memset(bprime,false,sizeof(bprime)) ;for(LL i=2; i<N; i+) {
   
   if(!bprime[i]) [prime[cnt++]=i;for(LL j=i*i; j<N; j+=i)bprime[il=true;
void getFactor(int n){
   
   
num= 0;
for(LL i=0;prime[i] *prime[i]<=n&&i<cnt; i++) {
   
   if(n%prime[il==0) [factor[num++]=prime[il;while(n%prime[il== 0)n/=prime[il;
//记录 n 的因子
if(n!=1)
//1 既不是素数,也不是合数
factor[num++]=n;
LI calculate(LL m,LL num) (
LL res=0;
for(LL i=l; i<(1<<num); i++) {
   
   
LL sum= 0;
LI temp=1;
for(LL j=0;j<num; j++) {
   
   
if(i&(1<<j)) {
   
   
sum+ + ;
temp *=factor[j];
if(sum%2)
res+=m/temp;
else
res-=m/temp;
return res;
int main() {
   
   
isprime();
LL a,b,n;
scanf("%1ld%lld号lld",&a,&b,&n);getFactor(n)//容斥定理,奇加偶减LL res= (b-(a-1)-calculate(b,num))+calculate(a-1,num);printf("lld\n",res);return 0;
  1. 求[1,n]中能/不能被m个数整除的个数

对于任意一个数a[i]来说,我们知道在1-n中有n/a[i]个数是a[i]的倍数,但这样将m个数扫一遍一定会用重复的数,因此需要用到容斥原理。

根据容斥定理的奇加偶减,对于m个数来说,其中的任意2,4,…,2k个数就要减去它们最小公倍数能组成的数,1,3,…,2k+1个数就要加上它们的最小公倍数,因此m个数就有2m种情况,对于每种状态,依次判断由多少种数组成,然后再进行奇加偶减即可。

根据容斥原理有: sum=从m中选1个数得到的倍数的个数-从m中选2个数得到的倍数的个数+从m中选3个数得到的倍数的个数-从m中选4个数得到的倍数的个数……

那么,能被整除的个数就是sum,不能被整除的个数就是n-sum。

LL GCD(IL a,LL b) {
   
   
return !b? a:GCD(b,ab) ;
LL LCM(LL a,LL b)[
return a/GCD(a,b) *b;
IL a[N];
int main(){
   
   
II n;
int m;
scanf("1ldd",&n, &m) ;for(int i=0;i<m;i++)scanf("%lld",&alil);
LL sum= 0;for(int i=0;i<(1<<m) ;i++){
   
   LL lcm= 1;LL cnt=0;for(int j=0;j<m;j++){
   
   if(i&(1<<j)){
   
   lcm=LCM(lcm,aljl) ;cnt++;
//2”种状态
//从 m 中选出个数
if(cnt!=0){
   
   
if(cnt&1)
//奇加
sum+=n/lcm;
else
//偶减
sum-=n/1cm;
printf(%lld "lld\n",sum,n-sum);return 0;
目录
相关文章
|
1天前
|
机器学习/深度学习 自然语言处理 算法
机器学习算法原理与应用:深入探索与实战
【5月更文挑战第2天】本文深入探讨机器学习算法原理,包括监督学习(如线性回归、SVM、神经网络)、非监督学习(聚类、PCA)和强化学习。通过案例展示了机器学习在图像识别(CNN)、自然语言处理(RNN/LSTM)和推荐系统(协同过滤)的应用。随着技术发展,机器学习正广泛影响各领域,但也带来隐私和算法偏见问题,需关注解决。
|
2天前
|
机器学习/深度学习 算法 C语言
【C言专栏】递归算法在 C 语言中的应用
【4月更文挑战第30天】本文介绍了递归算法在C语言中的应用,包括基本概念(通过调用自身解决子问题)、特点(调用自身、终止条件、栈空间)和实现步骤(定义递归函数、分解问题、设置终止条件、组合解)。文中通过阶乘计算和斐波那契数列两个案例展示了递归的使用,强调了递归可能导致的栈溢出问题及优化需求。学习递归有助于理解和应用“分而治之”策略。
|
3天前
|
机器学习/深度学习 数据可视化 算法
【Python机器学习专栏】t-SNE算法在数据可视化中的应用
【4月更文挑战第30天】t-SNE算法是用于高维数据可视化的非线性降维技术,通过最小化Kullback-Leibler散度在低维空间保持数据点间关系。其特点包括:高维到二维/三维映射、保留局部结构、无需预定义簇数量,但计算成本高。Python中可使用`scikit-learn`的`TSNE`类实现,结合`matplotlib`进行可视化。尽管计算昂贵,t-SNE在揭示复杂数据集结构上极具价值。
|
3天前
|
机器学习/深度学习 算法 数据挖掘
【Python机器学习专栏】层次聚类算法的原理与应用
【4月更文挑战第30天】层次聚类是数据挖掘中的聚类技术,无需预设簇数量,能生成数据的层次结构。分为凝聚(自下而上)和分裂(自上而下)两类,常用凝聚层次聚类有最短/最长距离、群集平均和Ward方法。优点是自动确定簇数、提供层次结构,适合小到中型数据集;缺点是计算成本高、过程不可逆且对异常值敏感。在Python中可使用`scipy.cluster.hierarchy`进行实现。尽管有局限,层次聚类仍是各领域强大的分析工具。
|
3天前
|
机器学习/深度学习 算法 前端开发
【Python机器学习专栏】集成学习算法的原理与应用
【4月更文挑战第30天】集成学习通过组合多个基学习器提升预测准确性,广泛应用于分类、回归等问题。主要步骤包括生成基学习器、训练和结合预测结果。算法类型有Bagging(如随机森林)、Boosting(如AdaBoost)和Stacking。Python中可使用scikit-learn实现,如示例代码展示的随机森林分类。集成学习能降低模型方差,缓解过拟合,提高预测性能。
|
4天前
|
存储 算法 搜索推荐
算法的复杂性与应用
算法的复杂性与应用
7 0
|
4天前
|
存储 算法 Python
数据结构与算法基础及在计算机科学中的应用
数据结构与算法基础及在计算机科学中的应用
8 0
|
4天前
|
机器学习/深度学习 算法 数据挖掘
【视频】支持向量机算法原理和Python用户流失数据挖掘SVM实例(下)
【视频】支持向量机算法原理和Python用户流失数据挖掘SVM实例(下)
11 0
|
4天前
|
机器学习/深度学习 算法 搜索推荐
【视频】支持向量机算法原理和Python用户流失数据挖掘SVM实例(上)
【视频】支持向量机算法原理和Python用户流失数据挖掘SVM实例
13 0
|
4天前
|
存储 机器学习/深度学习 算法