【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 }

转载于:https://www.cnblogs.com/DrunBee/archive/2012/09/06/2673399.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值