HDU 1796 How many integers can you find (容斥定理 + 二进制)

How many integers can you find

Time Limit: 12000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 5493    Accepted Submission(s): 1567

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 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

今天扣了一下容斥定理,离散结构中有,却是不记得了,总结一下,实现容斥原理大致有三种方法:dfs,队列数组,二进制,可以按照实际情况以及个人爱好自己选择

容斥定理内容:



大家可以理解为奇数个的并集则是加,偶数个的并集则是减,具体的建议大家翻阅资料了解原理

这道题目很明显符合容斥定理,所以我就用二进制过了


#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int MAXN = 50 + 5;
int n, m;
LL A[MAXN];
LL gcd(LL a,LL b) {
    return b ? gcd(b, a % b) : a;
}
LL lcm(LL a,LL b) {
    return a / gcd(a, b) * b;
}
int main() {
    while(~ scanf("%d%d", &n, &m)) {
        for(int i = 0; i < m; i ++) {
            scanf("%I64d", &A[i]);
        }
        int ms = 0;
        for(int i = 0 ;i < m;i ++){
            if(A[i] == 0) continue;
            A[ms ++] = A[i];
        }
        m = ms;
        LL ans = 0;
        for(int i = 1; i < (1 << m); i ++) {
            int bits = 0;
            LL res = 1;
            for(int j = 0; j < m; j ++) {
                if(i & (1 << j)) {
                    bits ++;
                    res = lcm(res, A[j]);
                }
            }
            if(bits & 1) ans += (LL)(n - 1) / res;
            else ans -= (LL)(n - 1) / res;
        }
        printf("%I64d\n", ans);
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-06 03:20:51

HDU 1796 How many integers can you find (容斥定理 + 二进制)的相关文章

hdu 1796 How many integers can you find 容斥定理

How many integers can you find Time Limit: 12000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) 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 t

hdu 1796 How many integers can you find 容斥第一题

How many integers can you find Time Limit: 12000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6710    Accepted Submission(s): 1946 Problem Description Now you get a number N, and a M-integers set, you should

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 容斥(入门

题目链接:点击打开链接 题意: 给出常数n, m个数的集合. 问: [0, n-1] 中有多少个数 是集合中 某个数的倍数. 思路: 求的是有多少个数至少被集合中一个数整除=能被集合中一个数整除-被2个整除+被3个整除··· #include <stdio.h> #include <iostream> #include <algorithm> #include <sstream> #include <stdlib.h> #include <

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

题意:给定一个数 n,和一个集合 m,问你小于的 n的所有正数能整除 m的任意一个的数目. 析:简单容斥,就是 1 个数的倍数 - 2个数的最小公倍数 + 3个数的最小公倍数 + ...(-1)^(n+1) * n个数的最小公倍数. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdl

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 <

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

HDU1796 How many integers can you find【容斥定理】

题目链接: http://acm.hdu.edu.cn/showproblem.php? pid=1796 题目大意: 给你一个整数N.和M个整数的集合{A1.A2.-.Am}.集合内元素为非负数(包括零),求小于N的 正整数(1~N-1)中,能被M个整数的集合中随意一个元素整除的正整数个数. 比如N = 12.M = {2,3},在1~N-1中,能被2整除的数为{2,4,6.8.10},能被3整除的数为 {3.6,9}.则所求集合为{2,3,4.6,8,9,10},共7个,则答案为7. 思路:

HDU 1695 GCD(容斥定理)

GCD Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 7529    Accepted Submission(s): 2773 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