How many integers can you find

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

Total Submission(s): 5556    Accepted Submission(s): 1593

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
 

题目大意:

求n以内可以被所给的集合中的数整除的数的个数。



解题思路:

这里要运用我们所说的容斥原理。

所谓容斥原理,运用起来要记住“奇加偶减”。

比方求100以内能被2,3,11,13,41整除的数的个数,我们即u(i)为100以内能被i整除的数的个数。

那么答案就是:

u(2)+u(3)+u(11)+u(13)+u(41)

-u(2*3)-u(3*11)-u(11*13)-u(13*41)

+u(2*3*11)+u(3*11*13)+u(11*13*41)

-u(2*3*11*13)-u(3*11*13*41)

+u(2*3*11*13*41)

这就是所谓的“奇加偶减”。

同一时候n以内能被i整除的数的个数为(n-1)/i。

综上。我们就能够通过枚举集合中的数,再容斥来得到答案。

枚举有2中方法:暴力枚举和dfs。因为m最大仅仅有10。暴力枚举时我们能够使用二进制来代表某个状态,每一位代表去与不取。dfs就非常easy了。

參考代码:

/*
二进制
Memory: 1568 KB Time: 639 MS
Language: G++ Result: Accepted
*/
#include<map>
#include<stack>
#include<queue>
#include<cmath>
#include<vector>
#include<cctype>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const double eps=1e-10;
const int INF=0x3f3f3f3f;
const int MAXN=25;
typedef long long LL; int n,m,num[MAXN],divi[MAXN]; int gcd(int a,int b)
{
return b?gcd(b,a%b):a;
} int lcm(int a,int b)
{
return a/gcd(a,b)*b;
} int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif // ONLINE_JUDGE
while(scanf("%d%d",&n,&m)!=EOF)
{
int cnt=0;
for(int i=0;i<m;i++)
{
scanf("%d",&num[i]);
if(num[i])
divi[cnt++]=num[i];
}
m=cnt;
int ans=0;
for(int k=1;k<(1<<m);k++)
{
int select=0,tlcm=1;
for(int i=0;i<m;i++)
{
if(k&(1<<i))
{
select++;
tlcm=lcm(tlcm,divi[i]);
}
}
if(select&1)
ans+=(n-1)/tlcm;
else
ans-=(n-1)/tlcm;
}
printf("%d\n",ans);
}
return 0;
}
/*
dfs
Memory: 1572 KB Time: 109 MS
Language: G++ Result: Accepted
*/
#include<map>
#include<stack>
#include<queue>
#include<cmath>
#include<vector>
#include<cctype>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const double eps=1e-10;
const int INF=0x3f3f3f3f;
const int MAXN=25;
typedef long long LL; int n,m,num[MAXN],divi[MAXN],ans; int gcd(int a,int b)
{
return b? gcd(b,a%b):a;
} int lcm(int a,int b)
{
return a/gcd(a,b)*b;
} void dfs(int pos,int tlcm,int select)
{
//if(pos>m)
// return ;
tlcm=lcm(tlcm,divi[pos]);
select++;
if(select&1)
ans+=(n-1)/tlcm;
else
ans-=(n-1)/tlcm;
for(int i=pos+1;i<m;i++)
dfs(i,tlcm,select);
} int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif // ONLINE_JUDGE
while(scanf("%d%d",&n,&m)!=EOF)
{
int cnt=0;
for(int i=0; i<m; i++)
{
scanf("%d",&num[i]);
if(num[i])
divi[cnt++]=num[i];
}
m=cnt;
ans=0;
for(int i=0;i<m;i++)
dfs(i,1,0);
printf("%d\n",ans);
}
return 0;
}

HDU 1796 How many integers can you find(容斥原理+二进制/DFS)的更多相关文章

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

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

    题意 就是给出一个整数n,一个具有m个元素的数组,求出1-n中有多少个数至少能整除m数组中的一个数 (1<=n<=10^18.m<=20) 题解 这题是容斥原理基本模型. 枚举n中有 ...

  3. HDU.1796 How many integers can you find ( 组合数学 容斥原理 二进制枚举)

    HDU.1796 How many integers can you find ( 组合数学 容斥原理 二进制枚举) 题意分析 求在[1,n-1]中,m个整数的倍数共有多少个 与 UVA.10325 ...

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

    题目链接 题意 : 给你N,然后再给M个数,让你找小于N的并且能够整除M里的任意一个数的数有多少,0不算. 思路 :用了容斥原理 : ans = sum{ 整除一个的数 } - sum{ 整除两个的数 ...

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

    题目传送:http://acm.hdu.edu.cn/diy/contest_showproblem.php?cid=20918&pid=1002 Problem Description    ...

  6. 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, y ...

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

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

  9. hdu 1796 How many integers can you find

    容斥原理!! 这题首先要去掉=0和>=n的值,然后再使用容斥原理解决 我用的是数组做的…… #include<iostream> #include<stdio.h> #i ...

随机推荐

  1. element-ui iview-admin 都是基于vue的ui框架

    element-ui iview-admin 都是基于vue的ui框架

  2. 小b重排字符串

    2485 小b重排字符串 2 秒 262,144 KB 5 分 1 级题   小b有一个字符串S,现在她希望重排列S,使得S中相邻字符不同. 请你判断小b是否可能成功. 样例解释:将"aab ...

  3. php简单实用的调试工具类

    <?php /* * 调试类 */ class Common_Debug { //打开错误报告 public static function showError($debug = true) { ...

  4. 「 HDU 1978 」 How many ways

    # 解题思路 记忆化搜索 一个点可以跳到的点,取决于它现在的能量.而且有一个显而易见的性质就是一条可行路径的终点和起点的横坐标之差加上纵坐标之差肯定小于等于起点的能量. 因为跳到一个点之后,能量和之前 ...

  5. Windows——bat中的路径和工具栏运行bat的坑

    工具栏添加的批处理环境 编写一个简单的批处理文件 set testEnv = %cd% pause 这里第一句:设置当前文件夹路径为环境变量testEnv的值 这里第二句:暂停命令窗口 第一次我们直接 ...

  6. mysql高效率随机获取n条数据写法

    今天做项目遇到这个问题,本来想用mysql自带的随机函数来实现,但是想到这样做功能是实现了,但是效率真的好差!一下子想不到好的方法,就去网上找了一下,记录下来,好好研究学习一下. ID连续的情况下(注 ...

  7. 常见的awk内建变量

    FS: 输入字段分隔符变量 语法: $ awk -F 'FS' 'commands' inputfilename 或者 $ awk 'BEGIN{FS="FS";}' OFS: 输 ...

  8. ruby cloud9部署到heroku

    Cloud9网址:https://c9.io/ 使用github账号登陆,如果没有,现在github(https://github.com/)上注册一个用户,在进行登陆.

  9. javascript中点击事件传入this的用法

    在script中有几种绑定事件的方法,有的在绑定函数中传入this参数,有的没有,那么,它们之间到底有什么区别呢? <!DOCTYPE html> <html lang=" ...

  10. 1. 垃圾收集简介 - GC参考手册

    说明: 在本文中, Garbage Collection 翻译为 “垃圾收集”, garbage collector 翻译为 “垃圾收集器”; 一般认为, 垃圾回收 和 垃圾收集 是同义词. Mino ...