题目链接:点击这里
暴力时间复杂度为 ,超时。
分析样例,有整数集合 ,质数
能被 整除的有
能被 整除的有
所以,根据容斥原理,
推广到 和 ,奇加偶减:
其中,能被 整除的集合元素个数为
由于互质,所以能被 同时整除的集合元素个数为
扫描二维码关注公众号,回复:
9904074 查看本文章
其它集合元素个数的计算方法以此类推。
我们知道,子集共有 个,可以利用二进制枚举子集,其时间复杂度为 ;每个子集还需要算一遍乘法,其时间复杂度为 ,因此,总时间复杂度为 。
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
typedef long long ll;
const int N = 20;
int n, m;
int p[N];
int main()
{
scanf("%d%d", &n, &m);
for(int i = 0 ; i < m; ++i) scanf("%d", &p[i]);
int res = 0;
for(int i = 1; i < 1 << m; ++i)
{
int t = 1, cnt = 0;
for(int j = 0; j < m; ++j)
{
if(i >> j & 1)
{
cnt++;
if((ll)t * p[j] > n) //p乘起来可能很大
{
t = -1;
break;
}
t *= p[j];
}
}
if(t != -1)
{
if(cnt & 1) res += n / t;
else res -= n / t;
}
}
printf("%d\n", res);
return 0;
}