zoukankan      html  css  js  c++  java
  • UVA10325 The Lottery [容斥原理]

    容斥入门题一道,蒟蒻的第一道自己yy出的容斥

    其实就是你统计出n以内能被整除的个数,再用总个数减去可行的个数,就是不可行的个数啦,但是对于231,显然不能枚举,那么就容斥吧。

    我们先对于一个数xn以内能被他整除的个数就是n/x向下取整这么多个,所以就可以O(1)的统计出这个个数。但对于多个数字,如果你加上对于xy分别的能被整除的个数的话,那么既能被x整除的又能被y整除的就多算了一次,(可以自己在本子上画维恩图理解),那么就要减去多算的个数,然后依次类推啦。

    上代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    ll n,m,a,b;
    ll ans,num[20];
    ll gcd(ll a,ll b){
        if(!b) return a;
        else return gcd(b,a%b);
    }
    ll lcm(ll a,ll b){
        return a/gcd(a,b)*b;
    }
    void dfs(int pos,ll a,int pd){
        ll now=-1ll;
        if(!pd) now=1ll;
        if(pos)ans+=(n/a)*now;
        else a=1;
        if(pos==m) return;
        for(int i=pos+1;i<=m;i++){
            dfs(i,lcm(a,num[i]),pd^1);
        }
    }
    int main(){
        while(scanf("%lld%lld",&n,&m)==2){
            ans=0;
            for(int i=1;i<=m;i++) scanf("%lld",&num[i]);
            dfs(0,0,1);
            printf("%lld
    ",n-ans);
        }
        return 0;
    }
    /*
    精简版
    void slove(int i,int a,long long v)
    {
        if(a%2)ans+=n/v;else ans-=n/v;
        for(;i<=m;i++)
         slove(i+1,a+1,lcm(v,num[i]));
    }
    int main()
    {
        while(scanf("%lld%d",&n,&m)==2)
        {
            for(int i=1;i<=m;i++)
             scanf("%lld",&num[i]);
            for(int i=1;i<=m;i++)
             slove(i+1,1,num[i]);
            printf("%lld
    ",n-ans);ans=0;
        }
        return 0;
    }
    */
  • 相关阅读:
    mysql的常用查询创建命令
    maven的简介
    google guava
    分库分表的情况下生成全局唯一的ID
    书单
    MD5Util
    UUID生成工具
    nodejs学习笔记三——nodejs使用富文本插件ueditor
    nodejs学习笔记二——链接mongodb
    mongodb 安装
  • 原文地址:https://www.cnblogs.com/VictoryCzt/p/10053453.html
Copyright © 2011-2022 走看看