首先推荐一篇介绍容斥原理很好的博客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-sum); 58 } 59 return 0; 60 }