您的位置:首页 > 其它

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

2016-05-18 22:03 441 查看
How many integers can you find
Time Limit:5000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u
Submit Status Practice HDU 1796

Description

Now you get a number N, and a M-integers set, you should find out how many integers which are small than N, that they can divided exactly by any integers in the set. For example, N=12, and M-integer set is {2,3}, so there is another set {2,3,4,6,8,9,10}, all the integers of the set can be divided exactly by 2 or 3. As a result, you just output the number 7.

Input

There are a lot of cases. For each case, the first line contains two integers N and M. The follow line contains the M integers, and all of them are different from each other. 0<N<2^31,0<M<=10, and the M integer are non-negative and won’t exceed 20.

Output

For each case, output the number.

Sample Input

12 2 2 3

Sample Output

7
分析:这几天练容斥有感觉,知道是容斥,但是却有问题,容斥是 互质的数,然后对于2,4这样的数就不会做了,太肤浅了,直接求最小公倍数啊,对啊,互质的相乘就是因为最小公倍数就是乘积啊=_=,弱!

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long LL;
int num[30], n, m, a[30];
LL res;
LL gcd(LL a, LL b)
{
if (a == 0)
return b;
return gcd(b % a, a);
}
void dfs(int cur, int snum, int cnt)
{
if (snum == cnt)
{
int temp = n;
int mult = 1;
for (int i = 0; i < snum; i++)
mult = mult / gcd(mult, a[i]) * a[i];  // 防爆
if (mult == 0)
return;
if (temp % mult == 0)
res += temp / mult - 1;
else
res += temp / mult;
return;
}
for (int i = cur; i < m; i++)
{
a[snum] = num[i];
dfs(i + 1, snum + 1, cnt);
}
}
int main()
{
int tm;
while (scanf("%d%d", &n, &tm) != EOF)
{
m = 0;
for (int i = 0; i < tm; i++)
{
int temp;
scanf("%d", &temp); // 去0
if (temp)
num[m++] = temp;
}
LL sum = 0;
for (int i = 1; i <= m; i++)
{
res = 0;
dfs(0, 0, i);
if (i & 1)
sum += res;
else
sum -= res;
}
printf("%I64d\n", sum);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: