容斥定理以及其应用

40 篇文章 2 订阅

下面仅仅是我在学习ACM中所遇到的应用场景,如果以后有遇到再另行补充

这里写图片描述
举个栗子:
这里写图片描述
以51nod 上的一道题说一下,题目意思是求解10以内不能被2 3 5 7整除的数的个数。
利用容斥定理,计算出能被2 3 5 7 整除的数的个数即:
ans=n/2+n/3+n/5+n/7n/6n/10n/14n/15n/21n/35+n/30+n/42+n/70+n/105n/210; a n s = n / 2 + n / 3 + n / 5 + n / 7 − n / 6 − n / 10 − n / 14 − n / 15 − n / 21 − n / 35 + n / 30 + n / 42 + n / 70 + n / 105 − n / 210 ;
然后用10减去ans就是最终答案。
①计算小于等于b的数中有多少跟b互素。
这也很明显可以用欧拉函数进行计算并且方便快解。
但如果得用每次计算的值呢,欧拉就不适用了,就比如POJ 1091需要计算一个序列不能有公因子。此时拿容斥就很好的解决了,计算出所有有公因子的,然后总数相减就是结果。
还可以计算小于等于a的数中跟b的所有素因子互质的数的个数。如HDU 1695
递归计算代码如下:

void dfs(int i,int nu,int x,int mu){
    ///数组下标,当前已经计算了的因子数,目前一共能够计算的因子数(传进来的),因子的乘积
    if(nu==x){
        sum+=b/mu;   //b是上文所说的小于等于的那个数
        return ;
    }if(i==cnt) return ;
    dfs(i+1,nu+1,x,mu*p[i]);   //p数组存放的即为素因子
    dfs(i+1,nu,x,mu);
}
int main()
{
    fac();    //计算所有的素因子
    ll ans = 0;
    for (int i = 1; i <= cnt; i++)   //cnt即素因子的个数
    {
        sum = 0;
        dfs(0,0,i,1);
        if(i & 1)ans += sum;
        else ans -= sum;
    }
    //计算出的ans即是跟素因子相关的数的个数
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值