首页 > 代码库 > 容斥原理

容斥原理

1, 求  {1, r} 中与 n 互质的个数:(容斥原理)

int solve (int n, int r)
{
    vector<int> p;
    for (int i=2; i*i<=n; ++i)
        if (n % i == 0)
        {
            p.push_back (i);
            while (n % i == 0)
                n /= i;
        }
    if (n > 1)
        p.push_back (n);
    int sum = 0;
    for (int msk=1; msk<(1<<p.size()); ++msk)
    {

        int mult = 1,bits = 0;
        for (int i=0; i<(int)p.size(); ++i)
            if (msk & (1<<i))
            {
                ++bits;
                mult *= p[i];
            }
        int cur = r / mult;
        if (bits % 2 == 1)
            sum += cur;
        else
            sum -= cur;
    }
    return r - sum;

}


2.   hdu   1796     How many integers can you find    (dfs 容斥原理写法)      

#include <stdio.h>
#include <algorithm>

using namespace std;

typedef __int64 LL;

int fac[12],top,ans,n;

int gcd(int a,int b)
{
    return b==0 ?a:gcd(b,a%b);
}

int lcm(int a,int b)
{
    return a/gcd(a,b)*b;
}

void dfs(int i,int cnt,int num,int m)
{
    if(cnt == m)
    {
        int sum = (n-1)/num;
        m&1 ? ans += sum : ans -= sum;
        return ;
    }
    if(top-i < m-cnt)
        return ;
    int LCM = lcm(num,fac[i]);
    if(LCM < n)
        dfs(i+1,cnt+1,LCM,m);
    dfs(i+1,cnt,num,m);
}

int main()
{
    while(~scanf("%d%d",&n,&top))
    {
        ans=0;
        for(int i=0;i<top;i++)
        {
            scanf("%d",&fac[i]);
             if(!fac[i])
                i--,top--;
        }
        for(int m=1;m<=top;m++)
            dfs(0,0,1,m);
        printf("%d\n",ans);
    }
    return 0;
}

                  



容斥原理