算法笔记--容斥原理应用

1.求1--r中与n互质的数的个数

位运算版:

ll count(ll n,ll r){
    p.clear();
    for(ll i=2;i*i<=n;i++){
        if(n%i==0){
            p.pb(i);
            while(n%i==0)n/=i;
        }
    }
    if(n>1)p.pb(n);
    ll ans=0;
    for(int i=1;i<(1<<p.size());i++){
        ll mask=1,cnt=0;
        for(int j=0;j<p.size();j++){
            if(i&(1<<j)){
                mask*=p[j];
                cnt++;
            }
        }
        if(cnt&1)ans+=r/mask;
        else ans-=r/mask;
    }
    return r-ans;
}

dfs版:

注意容斥和上面的相反,t==0的时候加了r,所以可以直接出结果

vector<int>p;
ll ans=0;
void dfs(int k,int cnt,ll s,ll r){
    if(k==p.size()){
        if(cnt&1)ans-=r/s;
        else ans+=r/s;
        return ; 
    }
    dfs(k+1,cnt,s,r);
    dfs(k+1,cnt+1,s*p[k],r);
}
ll count(ll n,ll r){
    p.clear();
    for(ll i=2;i*i<=n;i++){
        if(n%i==0){
            p.pb(i);
            while(n%i==0)n/=i;
        }
    }
    if(n>1)p.pb(n);
    ans=0;
    dfs(0,0,1,r);
    return ans;
}

 参考:http://blog.csdn.net/acdreamers/article/details/9721139

原文地址:https://www.cnblogs.com/widsom/p/8419162.html