【题目描述】
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

【题目分析】
首先我们需要学习一下容斥原理,不懂的话可以移步去看一下这篇大佬的博客:传送门
里面讲的很详细,除去证明之类的,我觉得比较重要的是容斥原理的公式


emm,看起来可能不太像人话,翻译一下就是几个集合的并集的元素的个数等于每个集合的个数减去集合两两相交的集合的元素的个数加上集合三三相交的集合的元素的个数……
然后我们就能解决这个问题啦,因为想求的是(0,n)(0,n)(0,n)内能被集合内元素整除的数的个数,我们把每个元素整除的数看作一个集合,那么我们想求的就是这些集合并集的元素的个数。而每个元素的个数挺好求的,就是(n-1)/元素的最小公倍数。
然后我们进行枚举就可以啦,只是直接枚举的话得需要用dfs稍微有些麻烦,我们用二进制枚举进行优化。
PS:PS:PS:题目说的是非负数,所以说有可能含0,注意读入的时候将0滤去。而且数字最大为n-1,取不到n

【AC代码】

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<climits>
#include<queue>
#include<vector>
#include<set>
#include<map>
using namespace std;typedef long long ll;
const int MAXN=15;
int a[MAXN];
int n,m,r;
int ans,sign,t;int gcd(int a,int b)
{return a%b==0?b:gcd(b,a%b);
}int main()
{while(~scanf("%d%d",&n,&m)){r=n-1;ans=0;int h=0;for(int i=0;i<m;i++){scanf("%d",&a[h]);if(a[h]) h++;}m=h;for(int i=1,limit=1<<m;i<limit;i++){sign=0; t=1;for(int j=0;j<m;j++){if(i&(1<<j)){sign++;t=a[j]/gcd(a[j],t)*t;}}if(sign%2){ans+=r/t;}else{ans-=r/t;}}printf("%d\n",ans);}return 0;
}

HDU - 1796——容斥原理+二进制枚举相关推荐

  1. 容斥原理(二进制枚举)

    在计数时,必须注意无一重复,无一遗漏.为了使重叠部分不被重复计算,人们研究出一种新的计数方法,这种方法的基本思想是:先不考虑重叠的情况,把包含于某内容中的所有对象的数目先计算出来,然后再把计数时重复计 ...

  2. HDU 5025Saving Tang Monk BFS + 二进制枚举状态

    3A的题目,第一次TLE,是因为一次BFS起点到终点状态太多爆掉了时间. 第二次WA,是因为没有枚举蛇的状态. 解体思路: 因为蛇的数目是小于5只的,那就首先枚举是否杀死每只蛇即可. 然后多次BFS, ...

  3. HPU组队赛B:问题(二进制枚举)

    时间限制1 Second 内存限制 512 Mb 题目描述 你有n个问题,你已经估计了第i个问题的难度为Ci,现在你想使用这些问题去构造一个问题集.比赛的问题集必须包含至少两个问题,而且比赛的总难度必 ...

  4. BZOJ1688|二进制枚举子集| 状态压缩DP

    Disease Manangement 疾病管理 Description Alas! A set of D (1 <= D <= 15) diseases (numbered 1..D) ...

  5. 116. 飞行员兄弟【二进制枚举】

    二进制枚举即可,需要注意的是,这道题和费解的开关还是有不同点的. 费解的开关枚举第一行就行了,因为它有依赖关系的. 而这个是一个十字形,无那种关系.故直接暴力枚举邓按不按的所有情况即可. #inclu ...

  6. 1362. 健康的荷斯坦奶牛【难度: 一般 / 二进制枚举】

    https://www.acwing.com/problem/content/1364/ 二进制枚举即可,取一个最小值. #include<bits/stdc++.h> using nam ...

  7. # 起床困难综合症(二进制枚举+按位求贡献)

    起床困难综合症(二进制枚举+按位求贡献) 题意:n扇门,每扇门包括一个运算op和数x,玩家有一个初始攻击力[0,m],经过n扇门后的值为最终伤害值.给出n和m,求最大伤害值. code: #inclu ...

  8. 【动态规划笔记】状压dp:蓝桥 矩阵计数 (二进制枚举)

    二进制枚举: 一共有n*m个位置,每个位置都有两种选择 ,所以用二进制枚举,并判断是否合理 二进制枚举操作: 枚举所有的二进制数 for(int i=0;i<n*m;i++)  判断二进制数1的 ...

  9. T^T找数字(搜索+二进制枚举)

    题目链接:传送门 解题思路:看一眼n的大小,发现只有20,所以我们可以用决策搜索,或者二进制枚举解决,用搜索做法则需要判断第i个位置是否选取,然后当前的总和是多少,其实用二进制枚举也是这样做的,我们判 ...

最新文章

  1. 模式的秘密-观察者模式(四)
  2. Log4j官方文档翻译(一、基本介绍)
  3. 阿里公开核心技术:如何摘下4项世界冠军,推理性能比第二名快5倍
  4. note for git
  5. 父类调用子类中的方法
  6. nmon监控linux内存,使用Nmon监控Linux系统性能
  7. 理想化的 Redis 集群
  8. 最课程阶段大作业之01:使用SVN实现版本控制
  9. 一文搞懂前端对象的深拷贝与浅拷贝
  10. 【递归练习】阿克曼函数
  11. 流水线、超流水线、超标量(superscalar)技术对比
  12. AngularJS入门
  13. C#WinForm实现雷速网站逆向
  14. 【云原生之kubernetes实战】在k8s环境下部署BookBrowser电子书浏览器
  15. Windows下禁止软件wps热点自启动和后台运行
  16. python 正则表达式生成器_正则表达式生成器
  17. 数据处理之seaborn的学习
  18. 【控制理论】MPC(一)
  19. 计算机专业要用多大显卡,吃鸡需要什么级别的显卡?或许跟你想的不太一样!...
  20. 6.2 用迹求特征多项式

热门文章

  1. 【2017级面向对象程序设计】第2次成绩排行
  2. Java基础知识学习04-自定义类、ArrayList集合
  3. WPF 反编译后错误处理
  4. cin、cin.get()、cin.getline()、getline()、gets()等函数的用法
  5. android 页面转换
  6. 关于重装系统后或打补丁后不能上网的问题的解决
  7. 分段函数if语句_C语言函数系列之库函数中基础必会函数(一)
  8. python数字转换_Python实现中文数字转换为阿拉伯数字的方法示例
  9. java开发 职业技能_java编程开发程序员需要具备哪些职业技能
  10. java获取页面标签_java获取网页源代码后,提取标签内容……