数学知识:容斥原理

   能被整除的数:

#include<iostream>
using namespace std;
typedef long long LL;

const int N = 20;
int p[N], n, m;//p[]存的i这个集合的质数的个数

int main() 
{
    scanf("%d%d",&n,&m);
    for(int i = 0; i < m; i++) scanf("%d",&p[i]);

    int res = 0;//答案
    
    //每一个i代表一种可能的取法,最外层的循环遍历置2的m次方后,可以取完所有的取法
    //从1开始枚举,枚举到1 << m(左移m位。左移一位相当于乘2(因为低位补0,高位舍去,但是1的高位都是0所以不影响),右移一位相当于除2),即2的m次方
    
    //这个是用位运算来作枚举,从1枚举到2的m次方减1把i看做一个二进制数,如i = 5(十进制下)= 00101(二进制下),表示p1、p3被选了
    //最外层的循环的作用是枚举从1到2的m次方减1的数,然后求出每个数的能被 p1,p2,…,pm 中的数整除的个数
    
    //例:m=2
    //1<<m=100,100的十进制是4,所以i<4,即找3次,也就是零个的,单个的,两个的(交集)
    for(int i = 1; i < 1 << m; i++)
    {
        int t = 1;//选中集合对应质数的乘积
        int s = 0;//选中的集合数量,即有几个1

        //枚举m个质数,依次计算容斥原理的公式,最多找0~<2也就是2个集合,也就是找单个集合的数量
        //后面多个集合的数量不看j<m了,而是看t*p[j]>n来确定数量
        for(int j = 0; j < m; j++)
        {
            //选中一个集合,如果当前这位是1就选择。j从0开始增加,所以i每次右移的位数不同,注意i没有发生变化,因为不是i=i>>j,没有=号
            //注意这里是右移,跟上面的左移相反
            if(i >> j & 1)
            {
                //如果t(已有的质数选法)乘上这个质数大于给定的数n,说明1∼n中的数不能被p整除,此时直接返回break,跳过这个质数
                if((LL)t * p[j] > n)
                {    
                    t = -1;
                    break;
                }
                s++;//有一个1,选中的集合数量+1
                t *= p[j];//每选中一个集合,就乘起来他的质数个数
            }
        }

        //再将提取出的取法代入公式
        //如果t不等于-1(-1是给定的flag值)
        if(t == -1) continue;  
        
        //根据容斥原理公式,这里其实是模拟(-1)^n-1奇数个集合是加,偶数个集合是减
        if(s & 1) res += n / t;//选中奇数个集合, 则系数应该是1, n/t为当前这种状态的集合数量
        else res -= n / t;//反之则为 -1
    }

    printf("%d\n",res);
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@katoumegumi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值