zoukankan      html  css  js  c++  java
  • HDU1796How many integers can you find(容斥原理)

         在计数时,必须注意无一重复,无一遗漏。为了使重叠部分不被重复计算,人们研究出一种新的计数方法,这种方法的基本思想是:先不考虑重叠的情况,把包含于某内容中的所有对象的数目先计算出来,然后再把计数时重复计算的数目排斥出去,使得计算的结果既无遗漏又无重复,这种计数的方法称为容斥原理。

    (1)两个集合容斥关系

    (2)三个集合容斥关系

     

    公式:

     这就是所谓的奇加偶减。

    贴个模版题:

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

    题目解析:

    这个题有bug,m可能为0。然后知道奇加偶减这个东西后,就可以深搜了,将所有组合情况全列出来,然后求lcm就好了。

    求1~(n-1)中被集合m中元素中整除的个数,没学容斥原理之前做这题肯定是会超时的。

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <queue>
    using namespace std;
    int n,m,top;
    __int64 a[12];
    int gcd(int A,int B)
    {
        return B==0?A:gcd(B,A%B);
    }
    //now为当前点,num为已经加入容斥的个数,lcm记录容斥的过程值(lcm),结果
    void dfs(int now,int num,__int64 lcm,__int64 &sum) { lcm=a[now]/gcd(a[now],lcm)*lcm; if(num&1) sum+=(n-1)/lcm; else sum-=(n-1)/lcm; for(int i=now+1; i<top; i++) dfs(i,num+1,lcm,sum); } int main() { int xx; while(scanf("%d%d",&n,&m)!=EOF) { top=0; for(int i=0; i<m; i++) { scanf("%d",&xx); if(xx!=0) { a[top++]=xx; } } __int64 sum=0; for(int i=0; i<top; i++) { dfs(i,1,a[i],sum); } printf("%I64d ",sum); } return 0; }
  • 相关阅读:
    学习笔记:字符串-Hash
    模板:高精度
    关于我自己
    学习笔记:数学-GCD与LCM-素数筛法
    学习笔记:数学-GCD与LCM-唯一分解定理(质因数分解)
    学习笔记:数学-GCD与LCM-整除的基础概念
    题解 洛谷P1990 覆盖墙壁
    学习笔记:平衡树-splay
    npm发布myself的插件
    javascript API文档
  • 原文地址:https://www.cnblogs.com/zhangmingcheng/p/4248176.html
Copyright © 2011-2022 走看看