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\n",ans);

    }



    return 0;

}


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

 

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

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

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

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

 

你可能感兴趣的:(Integer)