容斥原理+dfs hdu1796

原题链接`HDU1796

容斥原理 (奇加偶减) 在这里插入图片描述
所以题目中的ans= A1的倍数的个数—A1,A2的最小公倍数的倍数的个数+A1,A2,A3的最小公倍数的个数—A1,A2,A3,A4的最小公倍数的个数…(以此类推 当然也要+A2的倍数的个数…+A3的倍数的个数…+A4的倍数的个数…)

方法①:使用dfs一个一个遍历
方法②:二进制拆分枚举(不会!)

下面是方法①的ac代码

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
typedef long long ll;
using namespace std;
int n,m,top;
ll a[12];
int gcd(int A,int B)
{
    return B==0?A:gcd(B,A%B);
}
//now为当前点,num为已经加入容斥的个数,lcm记录容斥的过程值(lcm),sum结果
void dfs(int now,int num,ll lcm,ll &sum)
{
    lcm= a[now] / gcd(a[now],lcm) * lcm;  //最小公倍数 
    if( num & 1 ) sum+=(n-1)/lcm;  //奇加偶减
    else sum-=(n-1)/lcm;
    for(int i=now+1; i<top; i++)   //遍历后面数的公倍数
        dfs(i,num+1,lcm,sum);    
}
int main()
{
    int xx;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        top=0;
        for(int i=0; i<m; i++)
        {
            scanf("%d",&xx);   //题目数据包含0 ,把0过滤掉 
            if(xx!=0)
            {
                a[top++]=xx;
            }
        }
        ll sum=0;
        for(int i=0; i<top; i++)   //每一个都从第一个开始 —然后第二个+第三个 这样子 
        {
            dfs(i,1,a[i],sum);
        }
        printf("%lld\n",sum);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值