#Vijos P1629#八

14 篇文章 0 订阅
3 篇文章 0 订阅

组合数学三

时间限制: 1 Sec  内存限制: 64 MB

题目描述

八是个很有趣的数字啊。八=发,八八=爸爸,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。


用Ax来表示在[ a , b ]能被x整除的数,则问题变为求 A8 ∩ (b - a + 1 - A(a[1]) ∪ A(a[2]) ∪ A(a[3]) ∪ .... ∪ A(a[n]) )
Ans = [a , b]中所有能被8整除的数的个数 - [a , b]中既能被8整除又能被其他数整除的数的个数
容斥原理求[a , b]中既能被8整除又能被其他数整除的数的个数

#include<iostream>//容斥原理
#include<cstdio>
#include<cmath>
using namespace std;
typedef unsigned long long ULL;
int a[16],b[16];
int N;
ULL A,B,ans;
ULL gcd(ULL a,ULL b){return b?gcd(b,a%b):a;}
void Dfs(int i,ULL num,int cnt){
	if(i>N){
		if(cnt&1)
			ans+=B/num-A/num;
		else ans-=B/num-A/num;
		return ;
	}
	Dfs(i+1,num/gcd(num,a[i])*a[i],cnt+1);
	Dfs(i+1,num,cnt);
}
int main(){
	scanf("%d",&N);
	for(int i=1; i<=N; ++i)
		scanf("%d",&a[i]);
	scanf("%llu%llu",&A,&B);
	Dfs(1,8,1);
	printf("%llu\n",ans);
	return 0;
}







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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值