ZOJ 2386 容斥原理

题意:给出n个数,和m(1<=m<=200 000 000),求1~M中能被这n个数其中任意一个数整除的个数;

分析:n范围很小,可以枚举选择被哪些数整除,被奇数个整数整除加m/这个n个数的公共最小公倍数;

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 int n,m,a[15];
 5 int gcd (int a,int b) {
 6     return b==0? a:gcd(b,a%b);
 7 }
 8 
 9 int lcm(int a,int b) {
10     return a*b/gcd(a,b);
11 }
12 
13 int multiple(int x,int* cnt) {
14     int res = 1;
15     *cnt = 0;
16     for(int i=0;i<n;i++) {
17         if(x&(1<<i)) {
18             (*cnt)++;
19             res = lcm(res,a[i]);
20         }
21     }
22     return res;
23 }
24 
25 int main()
26 {
27 
28     while(scanf("%d%d",&n,&m)!=EOF) {
29         int ans = 0;
30         for(int i=0;i<n;i++)
31             scanf("%d",&a[i]);
32         int k;
33         for(int i=1;i<(1<<n);i++) {
34             int lcms = multiple(i,&k);
35             if(k&1) ans+= m/lcms;
36             else ans-=m/lcms;
37         }
38         printf("%d
",ans);
39     }
40 
41     return 0;
42 }
View Code
原文地址:https://www.cnblogs.com/TreeDream/p/7028554.html