数论之————容斥原理

容斥原理是一种计数方法。

这种方法的基本思想是:先不考虑重叠的情况,把包含于某内容中的所有对象的数目先计算出来,然后再把计数时重复计算的数目排斥出去,使得计算的结果既无遗漏又无重复

举个例子
1.两个集合的情况
这里写图片描述
A,B是两个集合
所以连个集合的并:|A + B| = |A| + |B| - |AB|
2.三个集合的情况
这里写图片描述
三个集合的并:|A + B + C| = |A| + |B| + |C| - |AB| - |AC| - |BC| + |ABC|
可以看出两种情况都减去了重复的部分。
可以得到如下等式:
这里写图片描述

所以我们怎么知道什么时候改减什么时候该加。

看元素个数,或者说集合个数,奇加偶减。

模板代码:
LL slove(LL N)  
{
  LL res=0;
  for(LL i=1;i<(1<<k);i++)
  {
      LL num=0;
      for(LL j=i;j!=0;j>>=1) num+=j&1;   //i的二进制表示中1的个数
      LL lcm=1;
      for(LL j=0;j<k;j++)
      {
          if(i>>j&1)
          {
              lcm=lcm/gcd(lcm,m[j])*m[j];  //求最小公倍数
              if(lcm>N) break;   //如果lcm>n,则n/lcm=0,因此在益处之前跳出
          }
      }
      if(num%2==0) res-=N/lcm;   //偶减
      else res+=N/lcm;           //奇加
  }
  return res;
}
另一种写法:
        ans = fac[n];
        flag = -1;//容斥的符号变化
        for(int i = 1; i <= n; i ++){
            ans += flag * fac[n] / fac[i];
            flag = -flag;  
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值