hdu 1796 容斥原理

来源:互联网 发布:stm32 压缩算法 编辑:程序博客网 时间:2024/06/04 19:05

How many integers can you find

Time Limit: 12000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 8973    Accepted Submission(s): 2681


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

Sample Output
7



题意:

给出m个数小于等于20的非负整数(注意0的情况)

对于小于n的数字里面,有多少个数可以被上面所说给集合里面任意一个数字整除

题解:

对于样例

18  2 

6    9

如果直接是进行除法容斥

18/6  +  18/9  - 18/(6+9)

是不对的,注意18这个数没并有好好处理

所以很容易想到需要用最大公约数



#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define LL long longLL a[100];LL n,m,ans;LL gcd(LL a,LL b){    return b?gcd(b,a%b):a;}LL lcm(LL a,LL b){    return a*b/gcd(a,b);}void dfs(int now,LL num,int sym){    if(num)  ans+=n/num*sym;    for(int i=now+1;i<=m;i++)        dfs(i,lcm(num,a[i]),-1*sym);}int main(){   // freopen("in.txt","r",stdin);    while(scanf("%lld%lld",&n,&m)!=EOF)    {        n--;        for(int i=1;i<=m;i++)            scanf("%d",&a[i]);        ans=0;        for(int i=1;i<=m;i++)            dfs(i,a[i],1);        printf("%lld\n",ans);    }    return 0;}


原创粉丝点击