容斥原理
来源:互联网 发布:js判断是否获取到元素 编辑:程序博客网 时间:2024/06/05 03:51
一、容斥原理
在计数时,要保证无一重复,无一遗漏。为了使重叠部分不被重复计算,在不考虑重叠的情况下,把包含于某内容中的所有对象的数目先计算出来,然后再把计数时重复计算的数目排斥出去,使得计算的结果既无遗漏又无重复,这种计数的方法称为容斥原理。
1.容斥原理1——两个集合的容斥原理
如果被计数的事物有A、B两类,那么,先把A、B两个集合的元素个数相加,发现既是A类又是B类的部分重复计算了一次,所以要减去。如图所示:
公式:A∪B=A+B-A∩B
总数=两个圆内的-重合部分的
2.容斥原理2——三个集合的容斥原理
如果被计数的事物有A、B、C三类,那么,将A、B、C三个集合的元素个数相加后发现两两重叠的部分重复计算了1次,三个集合公共部分被重复计算了2次。
如图所示,灰色部分A∩B-A∩B∩C、B∩C-A∩B∩C、C∩A-A∩B∩C都被重复计算了1次,黑色部分A∩B∩C被重复计算了2次,因此总数A∪B∪C=A+B+C-(A∩B-A∩B∩C)-(B∩C-A∩B∩C)-(C∩A-A∩B∩C)-2A∩B∩C=A+B+C-A∩B-B∩C-C∩A+A∩B∩C。即得到:
公式:A∪B∪C=A+B+C-A∩B-B∩C-C∩A+A∩B∩C
总数=三个圆内的-重合两次的+重合三次的
上面只是简单介绍一下容斥原理,那么代码如何写呢
就可以看看一篇讲的比较好的博客,里面有具体的实现方法还包括欧拉函数和抽屉原理的讲解。
点击打开博客http://blog.csdn.net/qq_36368339/article/details/70217849
附上两个实际的例子:
题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1284
我只是单纯的应用到了这个原理,代码写得有点直接。
正确代码:
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;typedef long long LL;const LL maxn=1e18;int main(){ LL n; while(~scanf("%lld",&n)) { LL a,b,c,d,ab,ac,ad,bc,bd,cd,abc,acd,abd,bcd,abcd;//15 a=n/2; b=n/3; c=n/5; d=n/7; ab=n/6; ac=n/10; ad=n/14; bc=n/15; bd=n/21; cd=n/35; abc=n/30; acd=n/70; abd=n/42; bcd=n/105; abcd=n/210; abc=abc-abcd;//仅包括同时能被2,3,5整除的数,下面得到的结果依次类推 abd=abd-abcd; acd=acd-abcd; bcd=bcd-abcd; ab=ab-(abc+abd+abcd); ac=ac-(abc+acd+abcd); ad=ad-(abd+acd+abcd); bc=bc-(abc+bcd+abcd); bd=bd-(abd+bcd+abcd); cd=cd-(acd+bcd+abcd); a=a-(ab+ac+ad+abc+abd+acd+abcd); b=b-(ab+bc+bd+abc+abd+bcd+abcd); c=c-(ac+bc+cd+abc+acd+bcd+abcd); d=d-(ad+bd+cd+abd+acd+bcd+abcd); LL ans; ans=n-(a+b+c+d+ab+ac+ad+bc+bd+cd+abc+abd+acd+bcd+abcd);//此时的各部分之间没有重叠 printf("%lld\n",ans); } return 0;}
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6106
容斥原理
正确代码:
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int main(){ int t; scanf("%d",&t); while(t--) { int n,maxn=-1; scanf("%d",&n); for(int i=0;i<n;i++) { int a,b,c,d,e,f,g,ab,bc,ac,abc; scanf("%d%d%d%d%d%d%d",&a,&b,&c,&d,&e,&f,&g); //接下来的操作将各部分之间重复的排除 d-=g;//ab e-=g;//bc f-=g;//ac a=a-(d+f+g); b=b-(d+e+g); c=c-(e+f+g); if(a<0||b<0||c<0||d<0||e<0||f<0||g<0)//判断数据是否有误 continue; int s=a+b+c+d+e+f+g; if(s>maxn) maxn=s; } printf("%d\n",maxn); } return 0;}
- 容斥原理
- 容斥原理 POJ3904
- 【容斥原理】八
- 【八】容斥原理
- 广义容斥原理
- 容斥原理
- 容斥原理 专题
- 容斥原理 专题
- hdu4390 容斥原理
- hdu1695 容斥原理
- HDU3929(容斥原理)
- 整除 容斥原理
- HDU4390(容斥原理)
- 容斥原理
- poj3904 容斥原理
- 容斥原理应用
- bzoj2393 容斥原理
- hdu4135 容斥原理
- 程序员编程7+1条小贴士
- 在cmd中运行.py文件
- 网络编程(二)--UDP
- C#winform应用程序连接sql server数据库代码
- CSS笔记
- 容斥原理
- ES6 —(let、const)
- (noip 模拟 Matrix)<逃避矩阵乘法的好方法#滑稽>
- 重载重写
- HDU
- 序列化和反序列化解决数组浅拷贝问题
- MySql查询性能优化
- 中国有一款超越HEVC的标准——AVS2标准简介
- 微信小程序简介