Vijos P1629 八
题目
描述
八是个很有趣的数字啊。八=发,八八=爸爸,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 数组只开到15,自己ZZ的WA了一发…)
对于所给出
然后,我们就需要去重
我们可以从中取出 cnt 个数字取最小公倍数之后的得到一个新的数字 sum
如果,
cnt
是偶数那么,就要加上
r
/
因为,若
sum
由
2
代码
#include<cstdio>
#define LL long long
using namespace std;
int n,l,r,ans;
LL a[20];
int readln()
{
int x=0;
char ch=getchar();
while (ch<'0'||ch>'9') ch=getchar();
while ('0'<=ch&&ch<='9') x=x*10+ch-48,ch=getchar();
return x;
}
LL gcd(LL x,LL y){return (y==0?x:gcd(y,x%y));}
void dfs(int i,LL sum,int cnt)
{
if (i>n) {
if (cnt&1) ans-=(r/sum-l/sum);
else ans+=(r/sum-l/sum);
}
else {
dfs(i+1,sum,cnt);
if (sum<=r) dfs(i+1,sum*a[i]/gcd(sum,a[i]),cnt+1);
}
}
int main()
{
n=readln();
for (int i=1;i<=n;i++) a[i]=readln();
l=readln()-1;r=readln();
dfs(1,8,0);
printf("%d",ans);
}