【ZOJ】3233 Lucky Number

题意:询问[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 }

你可能感兴趣的:(number)