题意:询问[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 }
posted on 2012-09-06 14:16  DrunBee  阅读(354)  评论(0编辑  收藏  举报