容斥原理及应用

1.公式:\left |S_{1} US_{2}US_{3}.....S_{n}\right | =\left | S_{1}\right |+\left | S_{2} \right |+\left | S_{3} \right |+......\left | S_{n} \right |(总共有C_{n}^{1}项)        -\sum_{i=1,j=1}^{n}\left | S_{i}\bigcap S_{j} \right |(总共有C_{n}^{2}项)        +     \sum_{i=1,j=1,k=1}^{n}\left | S_{i}\bigcap S_{j}\bigcap S_{k} \right |(总共有C_{n}^{3}项)然后再减四项的,再加五项的,以此类推。

2.从公式可以看出总共有C_{n}^{1}+C_{n}^{2}+C_{n}^{3}+......C_{n}^{n-1}+C_{n}^{n},如果再在左侧加一个C_{n}^{0}是不是总共就有2_{n}-1项,为什么能,从上述公式可以看出,从n个中选0个,选一个,选两个,一直到n个,是不是就是从n个集合中选任意多个集合的意思,有选或者不选两种可能,总共n给数所以是2_{n}-1(上述公式我们补了一个C_{n}^{0},所以减一)。

 证明:

不妨假设x,在k个集合中;

那么我们来求k被加了多少次,观察C_{n}^{1}+C_{n}^{2}+C_{n}^{3}+......C_{n}^{n-1}+C_{n}^{n}式子可知k被加了C_{k}^{1}-C_{k}^{2}+C_{k}^{3}-C_{k}^{4}+C_{k}^{5}.......-C_{k}^{k} ,如图:

例题:

1活动 - AcWing(能被整除的数)

 

 1.分析题目为什么是使用容斥定理,题目需要我们求1~n的范围内,能被p1,p2,...pm中至少一个整除的数总共有多少个,如果我们不是用容斥定理,我们就要算出每一个质数,能整除的数有那些,算出来之后,很明显,有一些数及能被这个数整除又能被那个数整除,所以这样算是非常麻烦的,所以我们需要用到容斥定理,

2.公式如下

\left | S_{i} \right |表示第i个质素能整除1~n中数的个数,那\left | S_{i} \right |怎么求能,求一个数能整除1~n中多少个数,就是

 n/\left | S_{i} \right |,有交集的又怎么求呢?有交集的就是他们的最小公倍数除以n(应为他们都是素数,他们的最小公倍数就是他们的乘积)。

 下面是代码:

#include<iostream>

using namespace std;

typedef long long ll;

const int N = 20;
ll n,m;
ll p[N];
ll res;

int main()
{
    cin>>n>>m;
    for(int i = 0;i < m;i ++)cin>>p[i];
    for(int i = 1;i < 1<<m;i ++)//由上述容斥定理公式可知,有二的n次幂减一项,这样枚举就想当面深搜暴力所有情况。
    {
        ll t = 1,cnt = 0;//t记录某个情况下那些奇数的积,cnt记录用了多少给集合。
        for(int j = 0;j < m;j ++)
        if(i>>j&1)
        {
            cnt++;
            if((ll)p[j]*t > n)//如果超过了n,那就没必要再求了(超范围了)。
            {
                t = -1;//记录一下这个情况
                break;
            }
            t *= p[j];
        }
        if(t!=-1)
        {
            if(cnt%2)res+=n/t;//如果是奇数个集合加,偶数个集合就是减(由公式可知)。
            else res -=n/t;
        }
    }
    cout<<res<<endl;
}

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值