容斥简述

来源:互联网 发布:下载淘宝2016新版本 编辑:程序博客网 时间:2024/05/12 10:43


先上容斥原理的百科定义

。。在计数时,必须注意没有重复,没有遗漏。为了使重叠部分不被重复计算,人们研究出一种新的计数方法,这种方法的基本思想是:先不考虑重叠的情况,把包含于某内容中的所有对象的数目先计算出来,然后再把计数时重复计算的数目排斥出去,使得计算的结果既无遗漏又无重复,这种计数的方法称为容斥原理。

。。(好吧我错了,不应该上这个的,额,那就再任性一点来个更抽象的)

公式

在概率论中,对于概率空间 ( Ω , F , P {\displaystyle (\Omega ,{\mathcal {F}},\mathbb {P} )}中的事件A1,……,An

n = 2时容斥原理的公式为:

P ( A 1 ∪ A 2 ) = P ( A 1 ) + P ( A 2 ) − P ( A 1 ∩ A 2 )
{\mathbb  {P}}(A_{1}\cup A_{2})={\mathbb  {P}}(A_{1})+{\mathbb  {P}}(A_{2})-{\mathbb  {P}}(A_{1}\cap A_{2}),

n = 3时,公式为:

P ( A 1 ∪ A 2 ∪ A 3 ) = P ( A 1 ) + P ( A 2 ) + P ( A 3 ) − P ( A 1 ∩ A 2 ) − P ( A 1 ∩ A 3 ) − P ( A 2 ∩ A 3 ) + P ( A 1 ∩ A 2 ∩ A 3 ){\mathbb  {P}}(A_{1}\cup A_{2}\cup A_{3})={\mathbb  {P}}(A_{1})+{\mathbb  {P}}(A_{2})+{\mathbb  {P}}(A_{3})-{\mathbb  {P}}(A_{1}\cap A_{2})-{\mathbb  {P}}(A_{1}\cap A_{3})-{\mathbb  {P}}(A_{2}\cap A_{3})+{\mathbb  {P}}(A_{1}\cap A_{2}\cap A_{3})

一般地:

P ( ⋃ i = 1 n A i ) = ∑ i = 1 n P ( A i ) − ∑ i , j : i < j P ( A i ∩ A j ) + ∑ i , j , k : i < j < k P ( A i ∩ A j ∩ A k ) −   ⋯   + ( − 1 ) n − 1 P ( ⋂ i = 1 n A i ) ,、{\mathbb  {P}}{\biggl (}\bigcup _{{i=1}}^{n}A_{i}{\biggr )}=\sum _{{i=1}}^{n}{\mathbb  {P}}(A_{i})-\sum _{{i,j\,:\,i<j}}{\mathbb  {P}}(A_{i}\cap A_{j})+\sum _{{i,j,k\,:\,i<j<k}}{\mathbb  {P}}(A_{i}\cap A_{j}\cap A_{k})-\ \cdots \ +(-1)^{{n-1}}\,{\mathbb  {P}}{\biggl (}\bigcap _{{i=1}}^{n}A_{i}{\biggr )},

也可以写成:

P ( ⋃ i = 1 n A i ) = ∑ k = 1 n ( − 1 ) k − 1 ∑ I ⊂ { 1 , … , n } | I | = k P ( A I ) ,
{\mathbb  {P}}{\biggl (}\bigcup _{{i=1}}^{n}A_{i}{\biggr )}=\sum _{{k=1}}^{n}(-1)^{{k-1}}\sum _{{\scriptstyle I\subset \{1,\ldots ,n\} \atop \scriptstyle |I|=k}}{\mathbb  {P}}(A_{I}),


不过我的理解是,也就是对于这个集合,求总数的时候,集合内数为奇则加,偶则减(关于证明略)

不过你可以用一个栗子来简单的理解(借用其他人博客)

举个例子,比如 k 的质因子有 2,3,5。那么2、3、5的倍数都不和 k 互质,另外还没有完,可能有重复的地方,比如6,既是2的倍数又是3的倍数,前面用 k/2 + k/3 的时候多减了,这个时候要加上 k / (2*3)。同理,10,15这一类数都应该加上。但是还有类似于30这样的数,它是2,3,5的倍数,减的时候又多减了。

然后我们会发现,出现奇数个数,就用加法,偶数个数用减法。

最后的式子是这样的:k / 2 + k / 3 + k / 5 - k / (2 * 3) - k / (3 * 5) - k / (2 * 5) + k / (2 * 3 * 5)

有点长,看一下容易发现我说的奇偶的规律。


对于每个数的选取可以将其转化成二进制的格式,有num个对应num位的二进制数(即2^num) 每一位的1或者0 对应这个位置q[i]数的取或者不取,

用一个二重循环来确定取数与否,取哪几个数组合,每次在num个取,取数为奇则总数加,为偶则减

因此可以总结一下构成代码如下:

(一个用来求质因数的倍数的个数的模板)

long long  solve(int num){    long long ans=0;    for(long long i=1;i<((long long )1<<num);i++)//共有num个数可选    {        long long p=1; //求值        int cnt=0;//所取数 数目        for(long long  j=0;j<num;j++)           {            if(((long long)1<<j)&i)//核心部分,取与不取就在此            {                p*=q[j];                cnt++;            }        }            if(cnt&1)                ans+=n/p;            else                ans-=n/p;    }    return ans;}

如果不懂的话可以输出((long long)1<<j)&i  来看一看(&是按位与,同为1才为1);

然后你就会发现每num个为一组,所有不为0的数表示此数取出进行组合,发现每组正好对应一种情况


真的奇妙

下面给一些不错的博客看看吧

1  这个比较长说的挺多点击打开链接

2 这个有很多容斥的题目点击打开链接

https://hrbust-acm-team.gitbooks.io/acm-book/content/combinatorics/rong_chi_yuan_li.html