题意:给出n和m个元素的集合,求小于n且是集合中任意元素的倍数的数有多少个(m<=10)。
最基础的容斥了,懒得DFS,直接枚举二进制暴力完事。
1 #include<cstdio> 2 #include<algorithm> 3 typedef long long LL; 4 #define MAXN 110 5 using namespace std; 6 int n, m, ans; 7 int a[MAXN]; 8 LL GCD(LL x, LL y) { 9 return y ? GCD(y, x % y) : x; 10 } 11 LL LCM(LL x, LL y) { 12 return x / GCD(x, y) * y; 13 } 14 LL Get(int x, int &cnt) { 15 int i; 16 LL res = 1; 17 for (i = cnt = 0; i < m; i++) { 18 if (x & (1 << i)) { 19 cnt++; 20 res = LCM(res, a[i]); 21 } 22 } 23 return res; 24 } 25 int main() { 26 int i, k; 27 LL tmp; 28 while (~scanf("%d%d", &n, &m)) { 29 n--; 30 k = m; 31 for (ans = i = 0; i < m; i++) { 32 scanf("%d", &a[i]); 33 if (a[i] == 0) 34 k = i; 35 } 36 if (k != m) { 37 m--; 38 swap(a[m], a[k]); 39 } 40 for (i = 1; i < (1 << m); i++) { 41 tmp = Get(i, k); 42 if (k & 1) 43 ans += n / tmp; 44 else 45 ans -= n / tmp; 46 } 47 printf("%d\n", ans); 48 } 49 return 0; 50 }