How many integers can you find HDU - 1796

原题链接

考察:容斥原理

入门题,我WA了两次...

坑点:

  1. m集合里有0,请务必看清题目做题
  2. res是集合的最小公倍数,if判断条件也要改成最小公倍数...

其他的就是acwing的模板题改改部分代码即可

 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
 4 typedef long long ll;
 5 const int N = 21;
 6 int p[N];
 7 ll gcd(ll a,ll b)
 8 {
 9     return b?gcd(b,a%b):a;
10 }
11 ll lcm(ll a,ll b)
12 {
13     return a*b/gcd(a,b);
14 }
15 int main()
16 {
17     int n,m;
18     while(scanf("%d%d",&n,&m)!=EOF)
19     {
20         n--;
21         ll ans = 0;
22         for(int i=0;i<m;i++) scanf("%d",&p[i]);
23         for(int i=1;i<1<<m;i++)//用二进制枚举选择了哪些集合
24         {
25             int cnt = 0;ll res = 1;
26             for(int j=0;j<m;j++)//0~m-1位,表示m个集合,该位为1表示他被选中
27                 if(i>>j&1)
28                 {
29                     if(lcm((ll)p[j],res)>n||res*p[j]<=0)
30                     {
31                         res = -1;
32                         break;
33                     }
34                     res = lcm((ll)p[j],res),cnt++;
35                 }
36             if(res!=-1)
37             {
38                 if(cnt&1) ans+=(ll)n/res;//表示res的倍数在1~n有多少个
39                 else ans-=(ll)n/res;
40             }
41         }
42         printf("%lld\n",ans);
43     }
44     return 0;
45 }

 

posted @ 2021-01-31 03:00  acmloser  阅读(58)  评论(0编辑  收藏  举报