数论——容斥原理、莫比乌斯函数由于某些玄学原因,有些公式的减号未显示,如果有的符号显示为空格,则默认为减号。

1、容斥原理:时间复杂度为

,下面会有证明。

举一个简单的例子:用韦恩图来思考,求

三个集合的原有元素的并集,那么结果为:

以此类推到

个圆的交集:用容斥原理的方法答案为所有单个集合的元素个数-所有两个集合互相交集的元素个数+所有三个集合互相交集的元素个数...

我们知道容斥原理公式一共涉及到的元素个数为:

。因为

,因此

,因此容斥原理公式一共涉及到的元素个数为

。关于此公式(

)的证明,我们可以假设等号左边为对于

个物品所有选法的总个数,等号右边考虑每个物品选与不选两种情况,因此等式成立。

因此容斥原理的时间复杂度为

容斥原理的证明:对于容斥原理

对于一个元素

,它在

个集合中,

,它本身被选择的次数为

。我们知道一个结论:

,因此对于每一个元素

,它只被计算了

次,证毕。

例题:AcWing 890. 能被整除的数

给定一个整数

个不同的质数

。请你求出

中能被

中的至少一个数整除的整数有多少个。

首先我们知道,在

个数中能被

整除的数的个数为

因此我们只需要根据容斥原理,求出可以被单个元素整除的个数之和-可以被两个元素整除的个数之和+可以被三个元素整除的个数之和...我们用位运算来求得答案,时间复杂度为

#include

#define int long long

using namespace std;

int p[20];

void work() {

int n, m;

cin >> n >> m;

for (int i = 0; i < m; i++) cin >> p[i];

int res = 0;

for (int i = 1; i < 1 << m; i++) {

int t = 1, s = 0;

for (int j = 0; j < m; j++)

if (i >> j & 1) {

if (t * p[j] > n) {

t = -1;

break;

}

t *= p[j];

s++;

}

if (t != -1) {

if (s % 2) res += n / t;

else res -= n / t;

}

}

cout << res << endl;

}

int32_t main() {

ios::sync_with_stdio(false);

cin.tie(0);

cout.tie(0);

int cas;

cas = 1;

while (cas--) work();

}

例题:AcWing 214. Devu和鲜花

个盒子,第

个盒子中有

枝花。同一个盒子内的花颜色相同,不同盒子内的花颜色不同。要从这些盒子中选出

枝花组成一束,求共有多少种方案。若两束花每种颜色的花的数量都相同,则认为这两束花是相同的方案。结果需对

取模之后方可输出。

我们先考虑:从

个盒子选

枝花,每个盒子的花的个数为无限个,问一共能选多少枝花?

此问题等价于从

个盒子选

花,那么每个盒子至少选

枝。那么此问题由等价于把

个点分成

份,我们可以用隔板法来做,一共有

个空隙,有

个板子,因此答案为

拓展到此问题,第

个盒子中有

枝花。那么我们可以反过来考虑,用总共的答案

减去其中第

个盒子被拿走了大于

枝花的方案。第

个盒子被拿走了大于

枝花的方案数为:假设此盒子已经被拿走了

枝花,那么等价于前面的问题,从

个盒子中共拿走

枝花的方案数,等价于从N个盒子拿走

的方案数,每个盒子至少被拿

枝。因此答案为

根据容斥原理来做,可知答案为总共的

减去所有

个盒子不满足的加上所有

个盒子不满足的减去所有

个盒子不满足的...

#include

#define int long long

using namespace std;

int A[20];

constexpr int mod = 1e9 + 7;

int down = 1;

int qmi(int a, int b, int p) {

int res = 1;

while (b) {

if (b & 1) res = res * a % p;

a = a * a % p;

b >>= 1;

}

return res;

}

int C(int a, int b) {

if (a < b) return 0;

int up = 1;

for (int i = a; i > a - b; i--) up = i % mod * up % mod;

return up * down % mod;

}

void work() {

int n, m;

cin >> n >> m;

for (int i = 0; i < n; i++) cin >> A[i];

for (int j = 1; j <= n - 1; j++) down = j * down % mod;

down = qmi(down, mod - 2, mod);

int res = 0;

for (int i = 0; i < 1 << n; i++) {

int a = n + m - 1, b = n - 1;

int sign = 1;

for (int j = 0; j < n; j++)

if (i >> j & 1) {

sign *= -1;

a -= A[j] + 1;

}

res = (res + C(a, b) * sign) % mod;

}

cout << (res % mod + mod) % mod << endl;

}

int32_t main() {

ios::sync_with_stdio(false);

cin.tie(0);

cout.tie(0);

int cas;

cas = 1;

while (cas--) work();

}

2、莫比乌斯函数:

我们举例一道经典的应用题,求

中与

互质的数的个数:那么根据容斥原理,设

中和

有公因子i的数的个数,答案为

,我们可以惊奇的发现,其答案为

我们可以根据线性筛质数在

的时间内算出前

个数的莫比乌斯数。

int primes[N], cnt;

bool st[N];

int mobius[N];

void init(int n) {

mobius[1] = 1;

for (int i = 2; i <= n; i++) {

if (!st[i]) {

primes[cnt++] = i;

mobius[i] = -1;

}

for (int j = 0; primes[j] * i <= n; j++) {

int t = primes[j] * i;

st[t] = true;

if (i % primes[j] == 0) {

mobius[t] = 0;

break;

}

mobius[t] = mobius[i] * -1;

}

}

}

AcWing 215. 破译密码

对于给定的整数

,有多少正整数对

,满足

,并且

组询问,

的数据范围为

根据数据的范围,我们可以推断出时间复杂度为

每次询问的问题等价于:有多少正整数对

,满足

,并且

。那么根据容斥原理:值为

,其答案为

,也就是

。我们可以推断出时间复杂度为

考虑把上述过程优化,发现,这个式子中虽然i要枚举

次,但是实际上因为整除的原因

的值很少,只有

个。

因为

是单调递减的,并且有的值相同,所以整个序列一共有有

个值。(证明:在分母为

之间,值的个数为

个值,在

之间,值的个数为

个值)。

表示

的取值不变的最大的

值,那么

,并且

,其中

证明

证明:

综上:将原来的序列分成

段,而且每次都会跳一段,所以总共会跳

次,时间复杂度就是

加上询问后总的时间复杂度为

#include

typedef long long ll;

using namespace std;

const int N = 50010;

int primes[N], cnt;

bool st[N];

int mobius[N], sum[N];

void init(int n) {

mobius[1] = 1;

for (int i = 2; i <= n; i++) {

if (!st[i]) {

primes[cnt++] = i;

mobius[i] = -1;

}

for (int j = 0; primes[j] * i <= n; j++) {

int t = primes[j] * i;

st[t] = true;

if (i % primes[j] == 0) {

mobius[t] = 0;

break;

}

mobius[t] = mobius[i] * -1;

}

}

for (int i = 1; i <= n; i++) sum[i] = sum[i - 1] + mobius[i];

}

void work() {

int a, b, d;

cin >> a >> b >> d;

a /= d, b /= d;

int n = min(a, b);

ll res = 0;

for (int l = 1, r; l <= n; l = r + 1) {

r = min(n, min(a / (a / l), b / (b / l)));

res += (sum[r] - sum[l - 1]) * (ll)(a / l) * (b / l);

}

cout << res << endl;

}

int32_t main() {

ios::sync_with_stdio(false);

cin.tie(0);

cout.tie(0);

init(N - 1);

int cas;

cin >> cas;

while (cas--) work();

}

c莫比乌斯函数_数论——容斥原理、莫比乌斯函数相关推荐

  1. 编写分段函数子函数_编写自己的函数

    编写分段函数子函数 PYTHON编程 (PYTHON PROGRAMMING) In Python, you can define your own functions. 在Python中,您可以定义 ...

  2. subtotal函数_星期五的Excel函数:将总计为SUBTOTAL的筛选列表

    subtotal函数 The Excel SUM function does a great job of adding numbers on a worksheet, and it's probab ...

  3. js 实现2的n次方计算函数_密码杂凑函数的基本性质探讨

    密码学研究的宗旨是保证数据和通信的机密性.完整性和认证性,其中完整性和认证性的实现依赖于一类关键的密码学函数---密码杂凑函数.密码杂凑函数通常用来计算数据的短"指纹"(也称杂凑值 ...

  4. mysql独有的函数_数据库之MySQL函数(一)

    一.数学函数 1.绝对值函数 ABS(x) :返回 x 的绝对值 mysql> select ABS(2),ABS(-2.3),ABS(-22); 返回的结果如下: 数学学得好的大佬应该知道(本 ...

  5. 什么是python函数_什么是python函数

    python函数是指组织好的.可重复使用的.用来实现单一或相关联功能的代码段.python函数包含系统中自带的一些函数.第三方函数.以及用户自定义的函数. 函数是可以实现一些特定功能的小方法或是小程序 ...

  6. python四大高阶函数_四大高阶函数

    目录 1. 匿名函数 在我们需要一个函数但又不想费神的去命名一个函数的场合下使用,这就是匿名函数 1 f = lambda x,y,z:x+y+z2 defF(x,y,z):3 return x+y+ ...

  7. 画分段函数_秃头节:“函数”段子已出炉高中数学题型分析

    高中数学函数题型整理解析版 函数图像 有关函数图象识别问题的常见题型及解题思路(1)由函数的定义域,判断图象左右的位置,由函数的值域,判断图象的上下位置:②由函数的单调性,判断图象的变化趋势:③由函数 ...

  8. ltrim函数_数据分析常用Excel函数

    Excel是我们工作中经常使用的一种工具,对于数据分析来说,这也是处理数据最基础的工具.本文介绍数据分析中最常用的Excel函数. 查找匹配类 文本数据清洗类 日期类 逻辑运算类 计算统计类 一.查找 ...

  9. mysql数据库支持的函数_数据库MySQL--常见函数

    函数:将一组逻辑语句封装在函数体中,对外暴露函数名 调用:select 函数名() from 表:(若用到表中的字段则家上'from 表') 函数分类:   1.单行函数(例:concate.leng ...

最新文章

  1. 虚拟方法及抽象方法在使用上的区别
  2. java 匿名类 实现接口_细谈 Java 匿名内部类 【分别 使用 接口 和 抽象类实现】...
  3. 电脑休眠和睡眠的区别_关机、睡眠、休眠有啥区别?微软说非特殊情况不要关机...
  4. jQuery 筛选
  5. linux下进程的创建代码,Linux下进程创建分析
  6. 快速排序和归并排序的区别,Python代码实现
  7. 【剑指 offer】(二十三)—— 从上往下打印二叉树(或曰层次遍历、广度优先遍历)
  8. 5.8 拉普拉斯算子和拉普拉斯矩阵,图拉普拉斯算子推导 意境级讲解
  9. JBPM工作流(八)——流程实例(PI)Process Instance
  10. MyEclipse 10.7(版本:eclipse 3.7.x-Indigo系列)安装activiti-eclipse-plugin插件(流程设计器)...
  11. 计算机管理模糊,电脑显示器显示有点模糊怎么办
  12. Chrome版本下载
  13. bc8-android导航,路畅A6导航刷机固件 4.09 CN-A6-GBDS-BC8-VIN-256-V1.51
  14. Andriod中插入百度广告的使用
  15. 用vim解压各种格式
  16. 习题:一圆型游泳池如图所示,现在需在其周围建一圆型过道,并在其四周围上栅栏。栅栏价格为35元/米,过道造价为20元/平方米。过道宽度为3米,游泳池半径由键盘输入。要求编程计算并输出过道和栅栏的造价。
  17. 【Linux】MBR磁盘分区表只能有四个分区?
  18. 免费PPT模板下载(不定时更新)
  19. sublime text 3 调色板插件
  20. IT十年人生过客-十一-新挑战

热门文章

  1. JavaScript(JS)有一组英文歌曲,按照歌曲名称的字母顺序从“A”到“Z”顺序排列,保存在一个数组中。
  2. C#快速随机按行读取大型文本文件 - 磊的博客 - sanshi_leilei - 和讯博客
  3. 数据家新三板挂牌上市
  4. 【leetcode】搜索二维矩阵 II
  5. 如何用Python计算特征重要性?
  6. 我们都一样,不甘平凡又害怕努力
  7. GUI编程(java)
  8. 没人谈论的 3 种从 ChatGPT 赚钱的方法,我测试过的建立被动收入流的行之有效的方法
  9. 4g网络设置dns地址_4G网速越来越慢?别再去过多的责怪运营商,不妨试试这几个方法...
  10. 服装网上销售“美国版”——互动+体验=成功