【 HDU - 1796】How many integers can you find (容斥原理,二进制枚举或者dfs)
题干:
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
题目大意:
给定n和一个大小为m的集合,集合元素为非负整数。为1...n内能被集合里任意一个数整除的数字个数。n<=2^31,m<=10
输入n和m,接下来m个数。多组输入数据。
解题报告:
就是个简单的容斥啦~直接暴力、。但是用二进制的话时间挺紧凑的吧感觉。。。
AC代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
const int MAX = 2e5 + 5;
ll a[MAX];
ll LCM(ll a,ll b) {return (a*b)/__gcd(a,b);
}
int main()
{ll n,m,tmp,tot,ans;while(~scanf("%lld%lld",&n,&m)) {tot=ans=0;for(int i = 1; i<=m; i++) {scanf("%lld",&tmp);if(tmp != 0) a[++tot] = tmp; }for(int i = 1; i<=(1<<tot)-1; i++) {ll k = 0,lcm = 1;for(int j = 0; j<=tot-1; j++) {if(i & (1<<j)) {k++;lcm =LCM(lcm,a[j+1]);}}if(k & 1) ans += (n-1) / lcm;else ans -= (n-1) / lcm; }printf("%lld\n",ans);}return 0 ;}
总结:
注意判0啊,不然就会出现Runtime Error(INTEGER_DIVIDE_BY_ZERO)、、、其实想想也是嘛,因为gcd没事,但是lcm的时候有问题,比如lcm(0,100) return (0*100)/100
这题还可以用dfs写:(234ms)
//234ms
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
int n,m,cnt;
ll ans,a[30];
ll LCM(ll a,ll b) {return (a*b)/__gcd(a,b);
}
void dfs(int cur,ll lcm,int id) {lcm=LCM(a[cur],lcm); //递归找两个数的最小公倍数(其中一个数还是集合里面上一个两个数的最小公倍数)所以lcm表示的真实意义是很多个数的最小公倍数if(id&1) ans+=(n-1)/lcm; //因为这题并不包含n本身,所以用n-1else ans-=(n-1)/lcm;for(int i=cur+1; i<cnt; i++)dfs(i,lcm,id+1); //id+1是表示如果上一次是奇数个数的倍数那么这次就是找的是偶数个数的倍数
}int main() {while(~scanf("%d%d",&n,&m)) {cnt=0;int x;while(m--) {scanf("%d",&x);if(x!=0)a[cnt++]=x;}ans=0;for(int i=0; i<cnt; i++)dfs(i,a[i],1);printf("%lld\n",ans);}return 0;
}
另一种dfs:(218ms)
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
int n,m,cnt;
ll ans,a[30];
ll LCM(ll a,ll b) {return (a*b)/__gcd(a,b);
}void dfs(int cur,ll lcm,int id) {if(cur == cnt) {if(id == 0) return ;if(id&1) ans += (n-1)/lcm;else ans-=(n-1)/lcm;return ;}dfs(cur+1,lcm,id);dfs(cur+1,LCM(lcm,a[cur+1]),id+1);
}int main() {while(~scanf("%d%d",&n,&m)) {cnt=0;int x;while(m--) {scanf("%d",&x);if(x!=0)a[++cnt]=x;}ans=0;dfs(1,a[1],1);dfs(1,1,0);printf("%lld\n",ans);}return 0;
}
附:
一种新奇的dfs的思路:(31msAC)
【 HDU - 1796】How many integers can you find (容斥原理,二进制枚举或者dfs)相关推荐
- HDU - 1796 How many integers can you find(容斥原理)
题目链接:点击查看 题目大意:给出一个n,再给出一个含有m个数的集合,问1~n-1中有多少个数可以被集合中的所有数字整除 题目分析:因为1~n-1中的每个数可能会被整除多次,所以我们可以利用容斥原理枚 ...
- HDU - 1796——容斥原理+二进制枚举
[题目描述] Now you get a number N, and a M-integers set, you should find out how many integers which are ...
- hdu 1796 How many integers can you find 容斥定理
一开始看 这里 这个文章博主写得很好. 当举容斥定理的所谓 奇数为负 偶数为正的时候. 我直接就认为是 a*b 了.实际上是lcm(a,b). 由于博文中的因子都是互素的(素数之间).所以lcm(a, ...
- 容斥原理学习(Hdu 4135,Hdu 1796)
题目链接Hdu4135 Co-prime Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth ...
- HDU - 5877 Weak Pair 2016 ACM/ICPC 大连网络赛 J题 dfs+树状数组+离散化
题目链接 You are given a rootedrooted tree of NN nodes, labeled from 1 to NN. To the iith node a non-neg ...
- HDU 4430 amp; ZOJ 3665 Yukari#39;s Birthday(二分法+枚举)
主题链接: HDU:http://acm.hdu.edu.cn/showproblem.php?pid=4430 ZJU:http://acm.zju.edu.cn/onlinejudge/showP ...
- hdu 1598 find the most comfortable road (并查集+枚举)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1598 find the most comfortable road Time Limit: 1000/ ...
- 【AtCoder - 2554】Choose Integers (找规律,或枚举)
题干: Problem Statement We ask you to select some number of positive integers, and calculate the sum o ...
- hdu 50722014鞍山现场赛C题(容斥原理+同色三角形)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5072: 题意:找出一个3元集合使集合中的两两互质,或两两不互质.这样的集合的个数. 分析:将每个数都幻 ...
最新文章
- 【 MATLAB 】any 函数介绍(确定是否有任意数组元素非零)
- PHP---微信JS-SDK获取access_token/jsapi_ticket/signature权限签名算法,php/thinkphp实现微信分享自定义文字和图片...
- 好程序员大数据独家解析-hadoop五大节点
- java(IO)读写文件乱码转换UTF-8问题
- CompletableFuture详解~cancel
- python移动平均线绘图_对python pandas 画移动平均线的方法详解
- C++冒泡排序(包含初级、正宗及改进三种实现)
- bzoj 3232: 圈地游戏【分数规划+最小割】
- java方法的理解、调用栈与异常处理
- 台式计算机cpu多好,2019台式处理器排行榜_台式机处理器排行榜 前六强详细介绍...
- VC++网络安全编程范例(2)-创建自签名证书
- js之table操作
- 神舟战神换cpu教程_神舟战神做工如何?神舟战神K650D-A29拆机图解教程
- sublime全解:从菜鸟到大师
- 编写一个压缩软件(Java实现版本)
- 待到凤凰花开季,惟愿前程皆似锦
- 未明学院:爬取微博关注列表,带你一窥“饭碗cp”的人际网
- vlan的几种划分方式
- 《MATLAB 神经网络43个案例分析》:第4章 神经网络遗传算法函数极值寻优——非线性函数极值寻优
- html用九张图片做出九宫图,.九图片详解和制作
热门文章
- [剑指offer][JAVA]面试题第[14-1、2]题[剪绳子][Leetcode][第343题][整数拆分][数学][动态规划][背包]
- python ssh脚本_ssh爆破(python脚本)
- matlab二元一次方程求解_2-函数的求解计算
- nginx 配置详解_Nginx 配置详解
- c++心形代码_c语言心形告白代码实现
- 1526B. I Hate 1111
- Codeforces Round #719 (A-C)
- python书写风格_以下两种风格 Python 写法,请问大家倾向哪种:)
- DocumentFragment使用
- html5 php idea,五个HTML5新特性