概念
Transclude of 数学#^193df4
时间复杂度
由组合数证明:
即在组合里挑1,挑2,挑3来做计算 即
应用
要挑选1-n中可以被所给质数整除的数的数量
判断是并集,是能被一个质数整除的数的集合并集之后的数量
用容斥原理 将每个集合的数量用 n/p 下取整表示(即能整数的数的数量) 只要选定一个p,就可以用上述公式算出其集合数量,再利用容斥原理相加可以得到最终数量
int main()
{
int n, m;
cin >> n >> m;
int p[N];
for(int i = 0; i < m; i ++)
{
cin >> p[i];
}
LL ans = 0;
//挑1-m中的质数,选中整除数的集合
for(int i = 1; i < 1 << m; i ++)
{
LL t = 1, cnt = 0;
for(int j = 0; j < m; j ++)
if(i >> j & 1) // 判断哪个位置上有1
{
cnt ++;
//判断当前选中的数是否都可以被n整除,不可以就不用算了
if(t * p[j] > n)
{
t = -1;
break;
}
t *= p[j];
}
if(t != -1)
{
if(cnt % 2) ans += n / t;
else ans -= n / t;
}
}
cout << ans << endl;
return 0;
}
这里运用了一些技巧
要挑选组合数,可以利用位运算来简化
将一组数模拟为一串01串,如果是1,就说明该数被挑选,这样恰可以表示出所有可能的情况
再利用位运算
if(i >> j & 1)
可以判断某一位上是否是1