求[a,b]中能被8整除但不能被给定n个数整除的数的个数,转化为分别求[1,a-1]和[1,b]中的数的个数。
然后首先在区间[1,x]中能被8整除的数的个数是x/8,但是有的是不符合要求的。
要求不能被给定的n个数整除,我们就把能被这n个数整除的同时又能被8整除的数去掉。
原本是奇加偶减,但是一开始选取了一个8,所以反过来 ,具体见代码。
#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;
#define ll long long
ll a[16],n,m,x,y;
ll ans;
ll gcd(ll a,ll b){
ll r;
while (b){
r=a%b;
a=b;
b=r;
}
return a;
}
ll calc(ll x){
ll ret=x/8;
for (int i=1;i<m;i++){
ll cnt=0,val=8;
for (int j=0;j<n;j++)
if (i & (1<<j)){
val=val*a[j]/gcd(val,a[j]);
cnt++;
}
if (cnt&1) ret-=x/val; //奇加偶减 但是一开始选取了一个8 所以反过来
else ret+=x/val;
}
return ret;
}
int main(){
scanf("%I64d",&n);m=1<<n;
for (int i=0;i<n;i++) scanf("%I64d",&a[i]);
scanf("%I64d%I64d",&x,&y);
ans=calc(y)-calc(x-1);
printf("%I64d\n",ans);
return 0;
}