题意:求 [low,high] 内有多少个数满足,这些数至少能整除一个 A[] 里面的数的同时不能整除任何所有B[]里面的数;
分析:设 A 为满足[low,high] 内可以整除A[] 内至少一个数的数量,B 为满足[low,high] 内可以整除B[] 内所有数的数量,则 ANS=A-AB,容斥一下就好了;
代码:
#include<cmath>
#include<cstdio>
#include<iostream>
using namespace std;
typedef long long ll;
const int N = 18;
int n,m;
ll low,high;
ll A[N];
ll gcd(ll a,ll b){
if(a==0) return b;
if(b%a==0) return a;
return gcd(b%a,a);
}
ll lcm(ll a,ll b){
ll g=gcd(a,b);
if((double)a/g*b>high) return high+1;
return a/g*b;
}
ll cal(ll M){
ll ans=0;
for(int i=1;i< 1<<n;i++){
int cnt=0;
ll res=1;
for(int j=0;j<n;j++){
if(i>>j&1) cnt++,res=lcm(res,A[j]);
}
if(cnt&1) ans+=M/res;
else ans-=M/res;
}
return ans;
}
int main()
{
while(~scanf("%d%d%lld%lld",&n,&m,&low,&high)&&n){
for(int i=0;i<n;i++) scanf("%lld",&A[i]);
ll LCM=1;
for(int i=0,v;i<m;i++){
scanf("%d",&v);
LCM=lcm(LCM,v);
}
ll ANS=cal(high)-cal(low-1);
for(int i=0;i<n;i++){
A[i]=lcm(A[i],LCM);
}
ANS-=cal(high)-cal(low-1);
printf("%lld\n",ANS);
}
}