uva 10325基础容斥

题目:给你一个数n以及m个数字,问1~n中不能被这m个数字整除的数字的个数。

分析:容斥原理、组合数学。数字1-n中能被a、b整除的数字的个数分别是n/a,n/b;

           则1-n中能被a或b整数的数字个数为n/a + n/b - n/lcm(a,b),

          (最后一项为同时被a、b整除的数字个数);

           推广后可知能被m个数整除的个数是

           分别整除 - 任意两数的lcm + 任意三个数的lcm - 任意四个数的lcm + ...

ac代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
typedef long long ll;
ll num[16];
ll gcd(ll a,ll b)
{
    if(b==0) return a;
    return gcd(b,a%b);
}
ll lcm(ll a,ll b)
{
    ll g=gcd(a,b);
    return a/g*b;
}
void solve(int n,int m)
{
    ll sum=0;
    for(int i=1;i<(1<<m);i++)// 二进制枚举
    {
       // cout<<i<<": ";
        int ret=0;
        ll temp=1;
        for(int j=0;j<m;j++)
        {
            if(i&(1<<j)) //
            {
         //      cout<<num[j]<<" ";
                ret++;
                temp=lcm(temp,num[j]);
            }
        }
       // cout<<endl;
        if(ret%2) sum+=(n/temp);
        else sum-=(n/temp);
    }
    cout<<n-sum<<endl;
}
int main()
{
    ll n;
    int m;
    while(cin>>n>>m)
    {
        for(int i=0;i<m;i++) cin>>num[i];
       // for(int i=0;i<ret;i++) cout<<num[i]<<' ';
        solve(n,m);
    }
    return 0;
}

 

posted @ 2017-08-02 19:46  猪突猛进!!!  阅读(186)  评论(0编辑  收藏  举报