题意:询问[low,high]中,A集合存在一个数是它的约数,且B集合存在一个数不是它的约数的个数。
答案就是满足A条件的个数,减去满足A条件且不满足B条件的个数。
1 #include<cstdio> 2 #include<cmath> 3 #define MAXN 550 4 #define EPS 1e-8 5 typedef long long LL; 6 int n, m, a[MAXN], b[MAXN]; 7 LL low, high, lcm; 8 LL GCD(LL x, LL y) { 9 return y ? GCD(y, x % y) : x; 10 } 11 LL LCM(LL x, LL y) { 12 LL g; 13 g = GCD(x, y); 14 if (x / g > high / y) 15 return high + 1; 16 return x / g * y; 17 } 18 LL Gao(int x, int &k) { 19 int i; 20 LL ans = 1; 21 for (i = k = 0; x; x >>= 1, i++) { 22 if (x & 1) { 23 k++; 24 ans = LCM(ans, a[i]); 25 } 26 } 27 return ans; 28 } 29 LL Count(LL val) { 30 int i, k; 31 LL res1, res2, tmp1, tmp2; 32 res1 = res2 = 0; 33 for (i = 1; i < (1 << n); i++) { 34 tmp1 = Gao(i, k); 35 tmp2 = LCM(lcm, tmp1); 36 if (k & 1) { 37 res1 += val / tmp1; 38 res2 += val / tmp2; 39 } else { 40 res1 -= val / tmp1; 41 res2 -= val / tmp2; 42 } 43 } 44 return res1 - res2; 45 } 46 int main() { 47 int i; 48 LL ans; 49 while (scanf("%d%d%lld%lld", &n, &m, &low, &high), n) { 50 for (i = 0; i < n; i++) 51 scanf("%d", &a[i]); 52 lcm = 1; 53 for (i = 0; i < m; i++) { 54 scanf("%d", &b[i]); 55 lcm = LCM(lcm, b[i]); 56 } 57 ans = Count(high) - Count(low - 1); 58 printf("%lld\n", ans); 59 } 60 return 0; 61 }