hdu1796 How many integers can you find

原题:http://acm.hdu.edu.cn/showproblem.php?pid=1796


用到了容斥原理。看到了很好的算法,直接采用了。

#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;
typedef __int64 int64;

int n, m, cnt, i, j, x;
int64 ans, a[30];

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

//id 为1 的时候, 计算本身集合的数量。id为2的时候, 计算重叠;
//反复加减, 不计算后面的情况,有点DP的味道。
void DFS(int cur, int64 lcm, int id)//i, a[i], 1
{
	lcm = a[cur] / gcd(a[cur], lcm) * lcm;
	if (id & 1)
		ans += (n - 1) / lcm;     //因为这题并不包含n本身,所以用n-1
	else
		ans -= (n - 1) / lcm;
	for (int i = cur + 1; i < cnt; i++)
		DFS(i, lcm, id + 1);
}

int main()
{
	while (~scanf("%d%d", &n, &m))//~end of file
	{
		cnt = 0;
		ans = 0;
		
		while (m--)
		{
			scanf("%d", &x);
			if (x != 0)    //除0的情况
				a[cnt++] = x;
		}
		
		for (i = 0; i < cnt; i++)
			DFS(i, a[i], 1);
		printf("%d\n", ans);
	}
	return 0;
}



转载于:https://my.oschina.net/u/1017188/blog/333608

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值