容斥性原理的应用(欧拉函数)

24 篇文章 0 订阅
24 篇文章 0 订阅

容斥原理:

原理1:有I,j,p三个条件,假设满足条件i成立的事件数量为Si,满足条件I,j同时成立的事件数量为Si*Sj,满足事件I,j,p同时成立的事件数量为Si*Sj*Sp。则至少满足I,j,p其中一个条件的事件个数为Si+Sj+Sp-SiSj-SjSp-SiSp+SiSjSp

原理2:有A,B,C三个事件,其中i事件成立的概率为Pi,则A,B,C中至少一个事件成立的概率为PA+PB+PC-PAPB-PAPC-PBPC+PAPBPC

特别说明:以上原理可以推广至多个事件的情况,那么,最终的结果函数为

                                                                          

引例1:三个矩形在同一个平面存在,且三个矩形形可以进行重叠,求三个正方形所围成的几合图形的面积。

                                                                                             

这样,由容斥性原理,S=S1+S2+S3-S12(12重叠的面积)-S13(13重叠的面积)-S23(23重叠的面积)+S123(123都重叠的面积)

引例2:给出n的唯一分解式,

n=p1a1 p2a2·……·pnan,pi为素因子)

求不大于n的所有正整数中,与n互素的数的个数。

np互素:当gcd(n,p)=1时,np互素。

定理:对于素数pnp互素,当且仅当n不是p的倍数。(证明很显然,略)

特别说明:n=Pa,那么不大于np的倍数的个数为Pa-1个。

证明:P*k= Pa  ,解得:k=Pa-1

所以,由容斥性原理,欧拉函数可以写成:

                                                         

公式的数学意义:满足k<=nkn互素的k的个数。

基本总数为n,首先减去是p1,p2,…,pk倍数的个数(由互素定理),然后加上同时是两个素因子的倍数的个数,再减去同时是三个素因子的倍数的个数……扩展至n

但是这样做在编程实现上并不占优势,时间复杂度甚至不如暴力解决。所以我们需要寻找更好的解决方式,但是对欧拉公式的理解至关重要。

由于数学家的贡献,可以知道欧拉公式等价于下面的形式。

                                                      

该公式可以利用数学归纳法进行证明,但是我们可以对该公式进行理解性记忆,对照在概率论中学过的两个公式:

1( 1 – p1 ) ( 1 - p2 ) = 1 – p1 – p2 + p1p2

2( 1 - p1 ) ( 1 - p2 ) ( 1 – p3 ) = 1 – p1 – p2 - p3 + p1p2 + p2p3 + p1p3– p1p2p3

这样,对该公式的记忆变得不那么突兀。

这样,该问题就变的很好解决了。

值得一提的是,该问题如果需要求k<=n的欧拉函数表,下面的代码可以在O(nloglogn)的时间复杂度内完成全部欧拉函数值的计算。

intans[n+1];

voidphi_table(int n)

{

       int i.j;

       for(i=0;i<=n;i++) ans[i]=0;

       ans[1]=1;

       for(i=0;i<=n;i++) if(!ans[i])

              for(j=I;j<=n;j+=i)

              {

                     if(!ans[j]) ans[j]=j;

                     ans[j]=ans[j]/i*(i-1);

}

}

对该代码的理解:实际上是正面枚举任何一个比n小的数j,有多少个比j小的数是i 的倍数。与n有关的任意数i可以写成下面的形式:

                              j=a*i+b

这样,易知,当且仅当b=0时,ji的倍数。

b的取值范围是0 ~ i-1i个数,而这i个数中只有1个是i的倍数。

由于a的可循环性,比j小的所有j个数中,每i个就有一个是i的倍数,其余均不是i的倍数,换句话说,其余i-1个数均与j互素。

这样的互素的数共有a = j / i 组,每组数中共有i-1个,所以满足条件的数共有j/i*(i-1)个。

这个理解是理解上述代码的基础。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值