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

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这样的数就不会做了,太肤浅了,直接求最小公倍数啊,对啊,互质的相乘就是因为最小公倍数就是乘积啊=_=,弱!

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <algorithm>
 5 using namespace std;
 6 typedef long long LL;
 7 int num[30], n, m, a[30];
 8 LL res;
 9 LL gcd(LL a, LL b)
10 {
11     if (a == 0)
12         return b;
13     return gcd(b % a, a);
14 }
15 void dfs(int cur, int snum, int cnt)
16 {
17     if (snum == cnt)
18     {
19         int temp = n;
20         int mult = 1;
21         for (int i = 0; i < snum; i++)
22             mult = mult / gcd(mult, a[i]) * a[i];  // 防爆
23         if (mult == 0)
24             return;
25         if (temp % mult == 0)
26             res += temp / mult - 1;
27         else
28             res += temp / mult;
29         return;
30     }
31     for (int i = cur; i < m; i++)
32     {
33         a[snum] = num[i];
34         dfs(i + 1, snum + 1, cnt);
35     }
36 }
37 int main()
38 {
39     int tm;
40     while (scanf("%d%d", &n, &tm) != EOF)
41     {
42         m = 0;
43         for (int i = 0; i < tm; i++)
44         {
45             int temp;
46             scanf("%d", &temp); // 去0
47             if (temp)
48                 num[m++] = temp;
49         }
50         LL sum = 0;
51         for (int i = 1; i <= m; i++)
52         {
53             res = 0;
54             dfs(0, 0, i);
55             if (i & 1)
56                 sum += res;
57             else
58                 sum -= res;
59         }
60         printf("%I64d\n", sum);
61     }
62     return 0;
63 }

时间: 2024-10-07 10:21:33

HDU 1796How many integers can you find(容斥原理)的相关文章

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

How many integers can you find Problem 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

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

这个题的m的数中居然有0啊,RE了好几次.... 初学容斥原理,这才知道还有奇加偶减这个东西,以前一直以为容斥原理不过是把重复的删掉就好了,.. 然后知道奇加偶减这个东西后,就可以深搜了,将所有组合情况全列出来,然后求lcm就好了.数的个数就是(n-1)/lcm,虽然我代码里写的是gcd..不要在意这些细节... #include <iostream> #include <string.h> #include <math.h> #include <queue>

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

题意 就是给出一个整数n,一个具有m个元素的数组,求出1-n中有多少个数至少能整除m数组中的一个数 (1<=n<=10^18.m<=20) 题解 这题是容斥原理基本模型. 枚举n中有多少m中元素的个数,在结合LCM考虑容斥. 1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<cmath> 5 #include<algorithm> 6 u

HDU 5768:Lucky7(中国剩余定理 + 容斥原理)

http://acm.hdu.edu.cn/showproblem.php?pid=5768 Lucky7 Problem Description When ?? was born, seven crows flew in and stopped beside him. In its childhood, ?? had been unfortunately fall into the sea. While it was dying, seven dolphins arched its body

HDU 1695 GCD(欧拉函数+容斥原理)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1695 题意:x位于区间[a, b],y位于区间[c, d],求满足GCD(x, y) = k的(x, y)有多少组,不考虑顺序. 思路:a = c = 1简化了问题,原问题可以转化为在[1, b/k]和[1, d/k]这两个区间各取一个数,组成的数对是互质的数量,不考虑顺序.我们让d > b,我们枚举区间[1, d/k]的数i作为二元组的第二位,因为不考虑顺序我们考虑第一位的值时,只用考虑小于i的情

hdu 1695 GCD【欧拉函数+容斥原理】

GCD Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 6253    Accepted Submission(s): 2291 Problem Description Given 5 integers: a, b, c, d, k, you're to find x in a...b, y in c...d that GCD(x, y

hdu1796 How many integers can you find 容斥原理

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 {

hdu How many integers can you find

题意:找出小于n是m个数每个数的倍数的数的个数. 思路:用二进制表示是那几个数的倍数. 二进制进行容斥,去掉小于0的数. 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 6 __int64 n,m,g; 7 __int64 a[1000],b[1000]; 8 9 __int64 gcd(__int64 a,__int64 b) 10 { 1

HDU 1796 How many integers can you find (状态压缩 + 容斥原理)

题目链接 题意 : 给你N,然后再给M个数,让你找小于N的并且能够整除M里的任意一个数的数有多少,0不算. 思路 :用了容斥原理 : ans = sum{ 整除一个的数 } - sum{ 整除两个的数 } + sum{ 整除三个的数 }………………所以是奇加偶减,而整除 k 个数的数可以表示成 lcm(A1,A2,…,Ak) 的倍数的形式.所以算出最小公倍数, //HDU 1796 #include <cstdio> #include <iostream> #include <