题意 : 给你N,然后再给M个数,让你找小于N的并且能够整除M里的任意一个数的数有多少,0不算。
思路 :用了容斥原理 : ans = sum{ 整除一个的数 } - sum{ 整除两个的数 } + sum{ 整除三个的数 }………………所以是奇加偶减,而整除 k 个数的数可以表示成 lcm(A1,A2,…,Ak) 的倍数的形式。所以算出最小公倍数,
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//HDU 1796 #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #define LL __int64 using namespace std ; LL sh[12] ; LL gcd(LL a,LL b) { return b == 0 ? a : gcd(b,a%b) ; } int main() { LL a,b ; while(~scanf("%I64d %I64d",&a,&b)) { int c ,j = 0; for(int i = 0 ; i < b ; i++) { scanf("%d",&c) ; if(c > 0 && c < a) sh[j++] = c ; } b = j; // sort(sh,sh+b); LL ans = 0 ; for(int i = 1 ; i < (1 << b) ; i++)//(1 << b)-1种情况 { LL num = 0 ,lcm = 1; for(int j = 0 ; j < b ; j++) { if(i & (1 << j)) { num ++ ; lcm = lcm*sh[j]/gcd(lcm,sh[j]) ; } } if(num & 1) ans += (a-1)/lcm ; else ans -= (a-1)/lcm ; } printf("%I64d\n",ans) ; } return 0 ; }