描述

八是个很有趣的数字啊。八=发,八八=爸爸,88=拜拜。当然最有趣的还是8用二进制表示是1000。怎么样,有趣吧。当然题目和这些都没有关系。

某个人很无聊,他想找出[a,b]中能被8整除却不能被其他一些数整除的数。

格式

输入格式

第一行一个数n,代表不能被整除的数的个数。

第二行n个数,中间用空格隔开。

第三行两个数a,b,中间一个空格。

输出格式

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

样例1
样例输入1

3
7764 6082 462
2166 53442

样例输出1

6378

限制

各个测试点1s

提示

对于30%的数据, 1≤n≤5,1≤a≤b≤100000。

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

分析

容斥原理题。
a n s ans ans = 用 8 的倍数的个数 - 8的倍数中能被其他数整除的个数 = ( 1 ) S 1 ( r x l 1 x ) \sum(-1)^{|S|-1} * (\left\lfloor\dfrac{r}{x}\right\rfloor-\left\lfloor\dfrac{l-1}{x}\right\rfloor) (1)S1(xrxl1)

代码如下

#include <bits/stdc++.h>
#define LL long long
using namespace std;
int ans, l, r, n;
int a[16]; 
int gcd(int a, int b){
	return !b? a: gcd(b, a % b);
}
void cal(LL x, int p, int flag){
	int i;
	if(x > r) return;
	ans += flag * (r / x - (l - 1) / x);
	if(p > n) return;
	for(i = p; i <= n; i++) cal(x * a[i] / gcd(x, a[i]), i + 1, -flag);
}
int main(){
	int i, j, m;
	scanf("%d", &n);
	for(i = 1; i <= n; i++) scanf("%d", &a[i]);
	scanf("%d%d", &l, &r);
	cal(8, 1, 1);
	printf("%d", ans);
	return 0;
}