容斥定理

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

 

也可表示为 设S为有限集, ,则 两个集合的容斥关系公式:A∪B =|A∪B| = |A|+|B| - |A∩B |(∩:重合的部分) 三个集合的容斥关系公式:|A∪B∪C| = |A|+|B|+|C| - |A∩B| - |B∩C| - |C∩A| + |A∩B∩C| 详细推理如下: 1、 等式右边改造 = {[(A+B - A∩B)+C - B∩C] - C∩A }+ A∩B∩C 2、文氏图分块标记如右图图:1245构成A,2356构成B,4567构成C 3、等式右边()里指的是下图的1+2+3+4+5+6六部分: 那么A∪B∪C还缺部分7。 4、等式右边[]号里+C(4+5+6+7)后,相当于A∪B∪C多加了4+5+6三部分, 减去B∩C(即5+6两部分)后,还多加了部分4。 5、等式右边{}里减去C∩A (即4+5两部分)后,A∪B∪C又多减了部分5, 则加上A∩B∩C(即5)刚好是A∪B∪C。

 例题:HDU 2204 http://acm.hdu.edu.cn/showproblem.php?pid=2204

思路:由于n的范围达到1e18,所以首先排除暴力,因此想到pow(n,a[i])(a[i]代表的是多少次方,所以是要开a[i]次方根)然后遍历每一个a[i],再根据容斥定理进行计算;a[i]的范围是[2,60],就可以将这些数据枚举出来,为了避免超时要减少递归中的重复子问题。如果两个数之间的最大公约数不为1,那就意味着会产生重复子问题,最后枚举出来的a数组的数据就是 a[i]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59};判断要使用a数组里元素的方法:直接遍历a数组里的17个元素,假如2^a[i] > n,那么就只需要a数组里前i个数。 例如n = 10时,i = 2; ans = pow(n,1 / a[0]) + pow(n,1 / a[1]) - pow(n,1 / (a[1] * a[0])).

具体代码如下:

#include <bits/stdc++.h>

using namespace std;

long long n;
int a[] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59};
long long ans = 0;
int j = 0;

void dfs(int i,int cou,unsigned long long sum)
{
    sum *= a[i];
    if(cou % 2 == 1)
        ans += (long long)pow(1.0 * n,(double)(1.0 / sum));
    else
        ans -= (long long)pow(1.0 * n,(double)(1.0 / sum));
    for(int k = i + 1;k < j;k++)
        dfs(k,cou + 1,sum);
}

int main()
{
    while(scanf("%lld",&n) != EOF)
    {
        j = 0;
        ans = 0;
        while(pow(2.0,(double)a[j]) <= n && j < 17)
        {
            j++;
        }
        for(int i = 0;i < j;i++)
            dfs(i,1,1);
        printf("%lld\n",ans);
    }
    return 0;
}

通过容斥定理解决的问题还有:HDU 1796、6286、4135……

转载于:https://www.cnblogs.com/Fancy-LZC/p/10677173.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值