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

这篇文章中讲到这个问题,这篇文章基本上把容斥原理解决的问题大体上都概括了,神文啊。http://www.cppblog.com/vici/archive/2011/09/05/155103.html

题意:给出n,和一些数字,求1-n-1之间多少个数能被这些数整除的。思路,去看上面这篇文章吧,注意预处理把数据这些数中0和整除的数给筛出来,取交集的时候求的是lcm,就没问题了。

 1 #include <cstdio>

 2 #include <cstring>

 3 #include <algorithm>

 4 #include <cmath>

 5 #define ll __int64

 6 using namespace std;

 7 int p[20],o[20];

 8 ll gcd(ll a,ll b)

 9 {

10     return b == 0 ? a:gcd(b,a%b);

11 }

12 int judge(int a,int len)

13 {

14     int i,j,num;

15     ll lcm,ans;

16     ans = 0;

17     for(i = 1;i < 1<<len;i ++)

18     {

19         num = 0;lcm = 1;

20         for(j = 0;j <= len-1;j ++)

21         {

22             if(i&(1<<j))

23             {

24                 num ++;

25                 lcm = lcm*p[j]/gcd(lcm,p[j]);

26             }

27         }

28         if(num&1)

29         ans += a/lcm;

30         else

31         ans -= a/lcm;

32     }

33     return (int)ans;

34 }

35 int main()

36 {

37     int n,m,i,j;

38     while(scanf("%d%d",&n,&m)!=EOF)

39     {

40         memset(o,0,sizeof(o));

41         for(i = 0; i <= m-1; i ++)

42             scanf("%d",&p[i]);

43         sort(p,p+m);

44         for(i = 0; i <= m-1; i ++)//预处理一下,写的有点繁琐

45         {

46             if(p[i] == 0)

47             {

48                 o[i] = 1;

49                 continue;

50             }

51             if(!o[i])

52             {

53                 for(j = i+1; j <= m; j ++)

54                 {

55                     if(p[j]%p[i] == 0)

56                     o[j] = 1;

57                 }

58             }

59         }

60         j = 0;

61         for(i = 0;i <= m-1;i ++)

62         {

63             if(!o[i])

64             p[j++] = p[i];

65         }

66         m = j;

67         printf("%d\n",judge(n-1,m));

68     }

69     return 0;

70 }

你可能感兴趣的:(Integer)