【容斥】 能被整除的数

传送门

题意

给定\(n\)\(m\)个不同的质数\(p_{1}, p_{2}, \dots, p_{m}\),问\(n\)能被\(p_{1}, p_{2}, \dots, p_{m}\)中至少\(1\)个数整除的个数是多少

数据范围

\(\begin{array}{l}1 \leq m \leq 16 \\ 1 \leq n, p_{i} \leq 10^{9}\end{array}\)

题解

二进制枚举所有数是否选取,即枚举交集。
\(m\)个都是质数所以都互质,能被整除两个数就是能整除他们的\(lcm\)即乘积。
对于任意的质数\(p\)\(n\)中包含能被\(p\)整除的数的个数为\(\left\lfloor\frac{n}{P}\right\rfloor\)
复杂度\(\\ O\left(2^{m} \times m\right)\)

Code

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int main(){
    int n,m;
    cin>>n>>m;
    vector<int>prime(m);
    for(int i=0;i<m;i++)
        cin>>prime[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*prime[j]>n){
                    t=-1;
                    break;
                }
                t*=prime[j];
            }
        if(t!=-1){
            if(cnt&1) res+=n/t;
            else res-=n/t;
        }
    }
    cout<<res<<endl;
}
posted @ 2020-05-20 22:16  Hyx'  阅读(333)  评论(0)    收藏  举报