ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

容斥原理

2021-12-24 23:05:56  阅读:183  来源: 互联网

标签:lfloor ... cup int cap 容斥 pd 原理


容斥原理

原型

image-20211224170532703.png

求n个相交的集合的元素总个数

原理

QQ浏览器截图20200807160444.png

例如:
image-20211224170933221.png

证明

设元素x在所有集合中出现了k次,然后写出等式,应用组合数恒等式
image-20211224212016723.png

例题

给定一个整数 n 和 m 个不同的质数 p1, p2, …,pm。

请你求出 1∼n 中能被 p1, p2, …,pm 中的至少一个数整除的整数有多少个。

例子

image-20211224213053528.png

如何计算?

设\(|S_{p_i}|\)为\(1- n\)中\(p_i\)的倍数的个数,则

\[|S_{p_i}| = \lfloor \frac{n}{p_i} \rfloor \\ |S_{p1} \cap S_{p2}\cap ...\cap S_{pn}| =\lfloor \frac{n}{p_1, p_2,...p_n的最小公倍数} \rfloor \\\overset{p_i均为质数}{=} \lfloor \frac{n}{p_1 p_2...p_n} \rfloor \]

由容斥原理有

\[|S_{p_1} \cup S_{p_2} \cup ... \cup S_{p_m}|\\ = |S_{p_1}| + |S_{p_2}| + ... + |S_{p_m}| - |S_{p_1} \cap S_{p_2}| - ... + |S_{p_1} \cap S_{p_2} \cap S_{p_3} | - ...\\ = \sum _{i}|S_i| - \sum _{i,j}|S_i \cap S_j| + \sum _{i,j,k}|S_i \cap S_j \cap S_k|-... \]

这里面一共有\(2^n - 1\) 项,对应了除了全部不取以外,每个集合取或不取的所有情况

于是我们要枚举所有的选法,常用的方法是使用位运算

//枚举
for (int i = 1; i < 2 << n; i ++ ){
    ...
}
//判断第k位是否为1
if (i >> k & 1){
    ...
}

代码

#include <iostream>
#include <algorithm>

using namespace std;

typedef long long LL;

const int N = 20;

int p[N];

int main(){
    int n, m;
    cin >> n >> m;

    for (int i = 0; i < m; i ++ ) cin >> p[i];

    int ans = 0;

    for (int i = 1; i < 1 << m; i ++ ){         //这里应把i看成二进制数,代表了一种选法的序列,代表了计算|S|的分母
        int pd = 1, cnt = 0;                    //pd(product)记录分母,若干个质数的乘积;cnt,有多少个质数,决定后面计算中是加是减
        for (int j = 0; j < m; j ++ ){          //j枚举i的第j位,i的每个第j位对应了某个集合要不要乘到分母里
            if (i >> j & 1){
                if ((LL)pd * p[j] > n){         //公式里不是所有的项都能计算,可能出现n小于某些数的乘积,故要特判
                    pd = -1;
                    break;
                }
                pd *= p[j];                     //更新
                cnt ++ ;
            }
        }
        if (pd != -1){
            if (cnt % 2 == 0) ans -= n / pd;    //按照公式计算
            else ans += n / pd;
        }
    }

    cout << ans << endl;
    return 0;
}

标签:lfloor,...,cup,int,cap,容斥,pd,原理
来源: https://www.cnblogs.com/tsrigo/p/15729500.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有