hdu1796 How many integers can you find 容斥原理

Posted yutingliuyl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu1796 How many integers can you find 容斥原理相关的知识,希望对你有一定的参考价值。


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
 


能被给出的第二行的数整除的数的个数。

sum=被一个整除-被两个整除+被三个整除-。

。。。。。

注意一个他自己本身不算



#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
#include<stack>
#pragma comment(linker,"/STACK:102400000,102400000")
#define pi acos(-1.0)
#define EPS 1e-6
#define INF (1<<24)
using namespace std;
int m,n,cnt;
int num[20];
int visi[20];
long long int sum;
long long int gcd(long long int a,long long int b) //最大公约数
{
if(b==0)
{
return a;
}
return gcd(b,a%b);
}
long long int lcm(long long int a,long long int b) //最小公倍数
{
    return a/gcd(a,b)*b;
}
void solve()
{
    int i,flag=0;//记录有多少个数
    long long int t=1,ans;
    for(i=0;i<cnt;i++)
    {
        if(visi[i])
        {
            flag++;
            t=lcm(t,num[i]);
        }
    }
    ans=n/t;
    if(n%t==0) ans--;
    if(flag%2==1) sum=sum+ans; //奇数加。偶数减
    else sum=sum-ans;
}
int main()
{
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        int i,j;
        int a;
        cnt=0;
        sum=0;
        for(i=0;i<m;i++)
        {
            scanf("%d",&a);
            if(a!=0) num[cnt++]=a;
        }
        //int m=cnt;
        int zhuang=1<<cnt;
        for(i=1;i<zhuang;i++) //状态
        {
            int tem=i;
            for(j=0;j<cnt;j++) //状态取数情况
            {
                visi[j]=tem&1;
                tem=tem>>1;
            }
            solve();
        }
        printf("%I64d\n",sum);
    }
    return 0;
}





以上是关于hdu1796 How many integers can you find 容斥原理的主要内容,如果未能解决你的问题,请参考以下文章

hdu1796 How many integers can you find 容斥原理

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

HDU-1796 How many integers can you find(组合数学dfs)

HDU1796 How many integers can you find容斥定理

HDU 1796 How many integers can you find 容斥

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