HDU 1796 How many integers can you find

来源:互联网 发布:如何学java软件工程师 编辑:程序博客网 时间:2024/05/04 07:04


题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1796


题意:给出范围[1,N]和m个数构成的一个集合,求范围内有多少个数可以被这个集合里的数整除。


思路:容斥定理模板,集合里的数可能为0,如果为0就不跳过。而且集合里的数不一定互质,所有要求一下最小公倍数。


#include <cstdio>#include <cmath>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>#include <stack>#include <map>#include <queue>#include <utility>using namespace std;#define rep(i,j,k) for (int i=j;i<=k;i++)#define Rrep(i,j,k) for (int i=j;i>=k;i--)#define Clean(x,y) memset(x,y,sizeof(x))#define LL long long#define ULL unsigned long long#define inf 0x7fffffff#define mod %100000007int m,n,temp;int mi[15];int gcd(int a,int b){    if (a%b==0) return b;    return gcd(b,a%b);}int lcm(int a,int b){    return a/gcd(a,b)*b;}int main(){    while(~scanf("%d%d",&n,&temp))    {        m = 0;        rep(i,1,temp)        {            scanf("%d",&mi[++m]);            if ( mi[m] == 0 ) m--;        }        int ans = 0;        int uplim = 1<<m;        rep(i,1,uplim-1)        {            int num = 0;            LL cnt = 1;            rep(j,0,m-1)                if ( i & (1<<j) )                {                    num++;                    cnt = lcm(mi[j+1],cnt);                }            if ( num & 1 ) ans+= (n-1)/cnt;            else ans -= (n-1)/cnt;        }        printf("%d\n",ans);    }    return 0;}


0 0
原创粉丝点击