容斥原理——uva 10325 The Lottery

首先推荐一篇介绍容斥原理很好的博客http://www.cppblog.com/vici/archive/2011/09/05/155103.html

题意:求1~n中不能被给定m个数中任意一个数整除的数的个数。

思路:n-sum(能被整除的个数)

明显用容斥原理:如10 - 能被2整除的数的个数 - 能被3整除的数的个数 + 能被6整除的数的个数

20-能被2整除的数的个数-能被4整除的数的个数+能被4整除的数的个数(2,4的最小公倍数)
加上或减去的是(n/某种组合的最小公倍数)
 1 #include<cstdio>
 2 #include<cmath>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<iostream>
 6 #include<memory.h>
 7 #include<cstdlib>
 8 #include<vector>
 9 #define LL long long int
10 using namespace std;
11 const int MAXN=1000;
12 const double eps=1e-8;
13 const int inf=0x3f3f3f3f;
14 
15 int n,m;
16 long long p[20];
17 long long gcd(long long a,long long b)
18 {
19     return b ? gcd(b,a%b):a;
20 }
21 long long lcm(long long a,long long b)
22 {
23     long long tmp=gcd(a,b);
24     return a/tmp*b;
25 }
26 
27 int main()
28 {
29     while(~scanf("%d%d",&n,&m))
30     {
31         for(int i=0;i<m;i++)
32         {
33         scanf("%lld",&p[i]);
34         }
35         int sum=0;
36         for(int i=1;i<(1<<m);i++)
37         {
38             LL mult=1;
39             int ones=0;
40             for(int j=0;j<m;j++)
41             {
42                 if(i&(1<<j))
43                 {
44                     mult=lcm(mult,p[j]);
45                     if(mult>n)
46                         break;
47                     ones++;
48                 }
49             }
50             if(mult>n)
51                 continue;
52             if(ones%2)
53                 sum+=n/mult;
54             else
55                 sum-=n/mult;
56         }
57         printf("%d\n",n-sum);
58     }
59     return 0;
60 }
View Code

 

 
posted @ 2015-10-10 11:31  yyblues  阅读(221)  评论(0)    收藏  举报