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

题目给一个数字集合,问有多少个小于n的正整数能被集合里至少一个元素整除。

当然是容斥原理来计数了,计算1个元素组合的有几个减去2个元素组合的LCM有几个加上3个元素组合的LCM有几个。注意是LCM。

  • 而[1,n]中能被x整除的数字有$ \lfloor \frac nx \rfloor$个,因为设有$t$个,$x \times t \leqslant n$。
  • 计算多个数LCM利用:$lcm(a,b)=a/gcd(a,b)\times b $,$lcm(a,b,c)=lcm(a,lcm(b,c))$
 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
 4 int gcd(int a,int b){
 5     if(b==0) return a;
 6     return gcd(b,a%b);
 7 }
 8 int lcm(int a,int b){
 9     return a/gcd(a,b)*b;
10 }
11 int getCnt(int s){
12     int res=0;
13     for(int i=0; i<10; ++i){
14         if((s>>i)&1) ++res;
15     }
16     return res;
17 }
18 int main(){
19     int n,m,a[10];
20     while(~scanf("%d%d",&n,&m)){
21         --n;
22         int t=0;
23         while(m--){
24             scanf("%d",&a[t]);
25             if(a[t]) ++t;
26         }
27         m=t;
28         int ans=0;
29         for(int i=1; i<(1<<m); ++i){
30             int res=1;
31             for(int j=0; j<m; ++j){ 
32                 if(a[j]==0 || ((i>>j)&1)==0) continue;
33                 res=lcm(res,a[j]);
34             }
35             if(getCnt(i)&1) ans+=n/res;
36             else ans-=n/res;
37         }
38         printf("%d\n",ans);
39     }
40     return 0;
41 }

 

posted @ 2016-02-04 20:15  WABoss  阅读(181)  评论(0编辑  收藏  举报