试题H:拯救阿拉德大陆(容斥原理+二进制枚举)

题解:

上述题意其实就是求1~n中有多少个是所给四个数字的倍数。
在这里插入图片描述
即 ans = n/a + n/b + n/c + n/d - n/lcm(a,b) - n/lcm(a,c) - n/lcm(a,d) - n/lcm(b, c) - n/lcm(b,d) - n/lcm(c,d) + n/lcm(a,lcm(b,c)) + n/lcm(a,lcm(b,d)) + n/lcm(a,lcm(c,d)) + n/lcm(b,lcm(c,d)) - n/lcm(lcm(a,b),lcm(c,d))

Code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll lcm(ll a,ll b){return a/__gcd(a,b)*b;}
int main()
{
    ll n,a[4],ans=0;
    cin>>n>>a[0]>>a[1]>>a[2]>>a[3];
    for(int i=1;i<(1<<4);i++){
        ll x=1;
        for(int j=0;j<4;j++){
            if(i&(1<<j)){
                x=lcm(x,a[j]);
            }
        }
        if(__builtin_popcount(i)&1)ans+=n/x;
        else ans-=n/x;
    }
    cout<<ans<<endl;
    return 0;
}
关于容斥原理:

在计数时,必须注意没有重复,没有遗漏。为了使重叠部分不被重复计算,人们研究出一种新的计数方法,这种方法的基本思想是:先不考虑重叠的情况,把包含于某内容中的所有对象的数目先计算出来,然后再把计数时重复计算的数目排斥出去,使得计算的结果既无遗漏又无重复。——摘自百度百科

假设被计数的事物有A、B、C三类,则A类和B类和C类元素个数总和A∪B∪C = A+B+C - A∩B - B∩C - C∩A + A∩B∩C。

根据上式可以发现总共有C(3,1)+C(3,2)+C(3,3)=7种集合情况,为23-1个,又对于A、B、C三类有取和不取,所以我们就可以利用二进制去枚举了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值