HDU 1796How many integers can you find(容斥原理)

How many integers can you find
Time Limit:5000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

Description

  Now you get a number N, and a M-integers set, you should find out how many integers which are small than N, that they can divided exactly by any integers in the set. For example, N=12, and M-integer set is {2,3}, so there is another set {2,3,4,6,8,9,10}, all the integers of the set can be divided exactly by 2 or 3. As a result, you just output the number 7.
 

Input

  There are a lot of cases. For each case, the first line contains two integers N and M. The follow line contains the M integers, and all of them are different from each other. 0<N<2^31,0<M<=10, and the M integer are non-negative and won’t exceed 20.
 

Output

  For each case, output the number.
 

Sample Input

12 2 2 3
 

Sample Output

7
分析:这几天练容斥有感觉,知道是容斥,但是却有问题,容斥是 互质的数,然后对于2,4这样的数就不会做了,太肤浅了,直接求最小公倍数啊,对啊,互质的相乘就是因为最小公倍数就是乘积啊=_=,弱!
 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <algorithm>
 5 using namespace std;
 6 typedef long long LL;
 7 int num[30], n, m, a[30];
 8 LL res;
 9 LL gcd(LL a, LL b)
10 {
11     if (a == 0)
12         return b;
13     return gcd(b % a, a);
14 }
15 void dfs(int cur, int snum, int cnt)
16 {
17     if (snum == cnt)
18     {
19         int temp = n;
20         int mult = 1;
21         for (int i = 0; i < snum; i++)
22             mult = mult / gcd(mult, a[i]) * a[i];  // 防爆
23         if (mult == 0)
24             return;
25         if (temp % mult == 0)
26             res += temp / mult - 1;
27         else
28             res += temp / mult;
29         return;
30     }
31     for (int i = cur; i < m; i++)
32     {
33         a[snum] = num[i];
34         dfs(i + 1, snum + 1, cnt);
35     }
36 }
37 int main()
38 {
39     int tm;
40     while (scanf("%d%d", &n, &tm) != EOF)
41     {
42         m = 0;
43         for (int i = 0; i < tm; i++)
44         {
45             int temp;
46             scanf("%d", &temp); // 去0
47             if (temp)
48                 num[m++] = temp;
49         }
50         LL sum = 0;
51         for (int i = 1; i <= m; i++)
52         {
53             res = 0;
54             dfs(0, 0, i);
55             if (i & 1)
56                 sum += res;
57             else
58                 sum -= res;
59         }
60         printf("%I64d\n", sum);
61     }
62     return 0;
63 }
View Code

 

posted @ 2016-05-18 22:03  zhaop  阅读(187)  评论(0编辑  收藏  举报