【组合数学】八(容斥原理)

32 篇文章 1 订阅
3 篇文章 0 订阅

先来看一下题目。

题目描述

八是个很有趣的数字啊。八=发,八八=爸爸,88=拜拜。当然最有趣的还是8用二进制表示是1000。怎么样,有趣吧。当然题目和这些都没有关系。 某个人很无聊,他想找出[a,b]中能被8整除却不能被其他一些数整除的数。

输入

第一行一个数n,代表不能被整除的数的个数。 第二行n个数,中间用空格隔开。 第三行两个数a,b,中间一个空格。 a < =b < =1000000000

输出

一个整数,为[a,b]间能被8整除却不能被那n个数整除的数的个数。

样例输入

3
7764 6082 462
2166 53442

样例输出

6378

提示

对于30%的数据, 1 ≤n ≤5,1 ≤a ≤ b ≤ 100000。
对于100%的数据,1 ≤ n ≤15,1 ≤ a ≤ b ≤ 10^9,N个数全都小于等于10000大于等于1。

分析

估计这道题80%的人看完题目过后就知道这道题的解法——容斥原理。我一开始就想到了,只是在考试的过程中没有实现%>_<% ,然后就没有AC.
所以用 Ax 来表示在区间内能被x整除的数,则问题就变为求

A8(ba+1Aa[1]Aa[2]Aa[3]....Aa[n])

Ans=[a,b]中所有能被8整除的数的个数-[a,b]中既能被8整除又能被其他数整除的数的个数
容斥原理求[a,b]中既能被8整除又能被其他数整除的数的个数

源代码

#include<cstdio>
#define LL long long
int n;
LL a,b,num[20],ans;
LL gcd(LL a,LL b){return b==0?a:gcd(b,a%b);}
LL lcm(LL a,LL b){return a*b/gcd(a,b);}
void dfs(int i,LL tmp,int cnt){
    if(i>n){
        if(cnt&1) ans+=b/tmp-a/tmp;
        else ans-=b/tmp-a/tmp;  
    }
    else{
        dfs(i+1,lcm(tmp,num[i]),cnt+1);
        dfs(i+1,tmp,cnt);
    }
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%lld",&num[i]);
    scanf("%lld%lld",&a,&b);
    dfs(1,8,1);
    printf("%lld",ans);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值