HDU 1796 容斥原理 How many integers can you find

题目连接   http://acm.hdu.edu.cn/showproblem.php?pid=1796


处男容斥原理  纪念一下  TMD看了好久才明白DFS...

先贴代码后解释

#include<cstdio>
#include<cstring>
using namespace std;
#define LL long long
#define N 11

LL num[N],ans,n;
int m,cnt;

LL gcd(LL a,LL b)
{
    int t;
    while(b)
    {
        t=a%b;
        a=b;
        b=t;
    }
    return a;
}


void dfs(int id,bool flag,LL LCM)
{
    LCM=num[id]/gcd(num[id],LCM)*LCM;
    if(flag)ans+=n/LCM;
    else ans-=n/LCM;
    int i;
    for(i=id+1;i<cnt;i++)
    {
        dfs(i,!flag,LCM);
    }
}

int main()
{
    int i;
    while(scanf("%lld%d",&n,&m)!=EOF)
    {
        ans=cnt=0;
        for(i=0;i<m;i++)
        {
            scanf("%lld",&num[i]);
            if(num[i])num[cnt++]=num[i];
        }
        n--;
        for(i=0;i<cnt;i++)
            dfs(i,1,num[i]);
        printf("%lld
",ans);
    }

    return 0;
}


DFS看不懂的话  一定去自己按树模拟一下,这是对难解的代码的最好方法之一

第一:小于n的数  所以n--别忘

第二:flag为1,说明是奇数层,加,为0,说明是偶数层要减

第三:小心  题中说的是非负数  所以判断是不是0

第四:注意DFS做容斥的方法,模拟一下  真的好理解

原文地址:https://www.cnblogs.com/suncoolcat/p/3320180.html