容斥原理+欧拉函数+抽屉原理

2024-04-10 18:38

本文主要是介绍容斥原理+欧拉函数+抽屉原理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

(1)容斥原理 :重要应用 求出一个数n在区间[1,m]里面有多少个数与它互质。假设数据不超过int型。

 

实现过程分为两步:

1, 求出m的质因子 并保存在数组里面;

2, 求出区间[1,n]里面有多少个数与m不互质。

 

代码:

 
  1. #include <cstdio>

  2. #include <cmath>

  3. int p[10];//保存质因子 int型n不会超过10个

  4. int k;//记录质因子个数

  5. void getp(int n)//求出n的质因子

  6. {

  7. int i;

  8. k = 0;//初始化

  9. for(i = 2; i*i <= n; i++)

  10. {

  11. if(n % i == 0)

  12. {

  13. p[k++] = i;//保存质因子

  14. while(n % i == 0)

  15. n /= i;

  16. }

  17. }

  18. if(n > 1) p[k++] = n;//本身是质数

  19. }

  20. int nop(int m)//求出区间[1,m]里面有多少个数与n不互质

  21. {

  22. int top = 0;//队列顶点

  23. int que[10100];

  24. int i, j, t;

  25. que[top++] = -1;//队列数组保存n所有质因子任意不相同组合的乘积

  26. for(i = 0; i < k; i++)

  27. {

  28. t = top;//利于下面计算

  29. for(j = 0; j < t; j++)

  30. {

  31. que[top++] = que[j] * p[i] * (-1);//奇加偶减

  32. }

  33. }

  34. int sum = 0;//统计个数

  35. for(i = 1; i < top; i++)

  36. sum += m / que[i];

  37. return sum;

  38. }

  39. int main()

  40. {

  41. int n, m;

  42. while(scanf("%d%d", &n, &m), n||m)//求区间[1,m]内有多少个数与n互质

  43. {

  44. getp(n);

  45. printf("%d\n", m-nop(m));

  46. }

  47. return 0;

  48. }


上面的代码实现是很简单的,也是很好理解的。 网上还有DFS版本,位运算版本的以及递归版本的,这里再给个递归的(另外本人理解不太透彻),至于其它两个有兴趣的可以上网查下。

 

递归版本:

 

 
  1. #include <cstdio>

  2. #include <cmath>

  3. int p[10];//保存质因子 int型n不会超过10个

  4. int k;//记录质因子个数

  5. void getp(int n)//求出n的质因子

  6. {

  7. int i;

  8. k = 0;//初始化

  9. for(i = 2; i*i <= n; i++)

  10. {

  11. if(n % i == 0)

  12. {

  13. p[k++] = i;//保存质因子

  14. while(n % i == 0)

  15. n /= i;

  16. }

  17. }

  18. if(n > 1) p[k++] = n;//本身是质数

  19. }

  20. int nop(int m, int t)//求出区间[1,m]里面有多少个数与n不互质

  21. {

  22. int i, sum = 0;

  23. for(i = t; i < k; i++)

  24. sum += m / p[i] - nop(m/p[i],i+1);

  25. return sum;

  26. }

  27. int main()

  28. {

  29. int n, m;

  30. while(scanf("%d%d", &n, &m), n||m)//求区间[1,m]内有多少个数与n互质

  31. {

  32. getp(n);

  33. printf("%d\n", m-nop(m, 0));

  34. }

  35. return 0;

  36. }


 

(2)欧拉函数:说白了,就是指一个数n在[1,n-1]区间有多少个数与它互质(和容斥原理一样的应用)。

比如说,euler[n] = m代表的意思是在区间[1,n-1]里面有m个数与n互质。

欧拉函数公式:(我们假设n的质因子有x,y) euler[n] = n * (1-1/x) * (1-1/y)。若有多个继续添上即可。

欧拉函数拓展:小于或等于n的数中(n > 1),与n互质的数的总和为:euler[n] * n / 2。

现给个实例:求区间[1,100]内所有数的欧拉函数。这里eu[1] = 1。我不知道会不会有一些题目eu[1] = 0。。。注意啊

 

求欧拉函数 有两个思路:

1, 筛素数打表,用数组记录每个数的欧拉函数(适用于n不是很大的情况,因为数组不能开无限大);

2, 直接求法计算单个欧拉函数,对于有些题目会比较慢(对于很大的n依然可以求解)。

 

筛素法:

 
  1. #include <cstdio>

  2. #include <cstring>

  3. #define MAX 100+1

  4. int eu[MAX];

  5. void euler()

  6. {

  7. int i, j;

  8. eu[1] = 1;//1的欧拉函数为1 看题目而定

  9. for(i = 2; i < MAX; i++)

  10. {

  11. if(!eu[i])

  12. {

  13. for(j = i; j < MAX; j += i)

  14. {

  15. if(!eu[j]) eu[j] = j;

  16. eu[j] = eu[j] * (i-1) / i;

  17. }

  18. }

  19. }

  20. }

  21. int main()

  22. {

  23. euler();

  24. for(int i = 1; i < MAX; i++)

  25. printf("%d\n", eu[i]);

  26. return 0;

  27. }



 

计算单个欧拉函数:

 

 
  1. #include <cstdio>

  2. #include <cstring>

  3. #define MAX 100+1

  4. int euler(int n)//求n的欧拉函数

  5. {

  6. int i;

  7. int eu = n;//欧拉函数

  8. for(i = 2; i*i <= n; i++)

  9. {

  10. if(n % i == 0)//质因子

  11. {

  12. eu = eu * (i-1) / i;

  13. while(n % i == 0)

  14. n /= i;//避免再次累加

  15. }

  16. }

  17. if(n > 1) eu = eu * (n-1) / n;//本身就是 质数

  18. return eu;

  19. }

  20. int main()

  21. {

  22. for(int i = 1; i < MAX; i++)

  23. printf("%d\n", euler(i));

  24. return 0;

  25. }


 

对于很多题目,容斥原理若和欧拉函数一起使用,或许会增加程序效率。

 

 

(3) 抽屉原理: 又称鸽巢原理,指的是n+1个苹果放进n个盒子里面,一定会有一个盒子有两个苹果。

定理: 一个由n个数构成的数列,总能找到若干个连续的数 使它们之和能被n整除。

证明: 对于数列里面的元素a[1],a[2],...... a[n]。我们可以构造一个数组sum[],用sum[ i ]来存储前i个元素之和(包括第i个元素)。

那么sum数组里面所有的元素只有两种情况:(1) 至少存在一个sum[ i ] 能被n整除;(2) 对于所有的sum[ i ] 都不能被n整除 。

 

情况(1):定理成立。。。

情况(2):首先我们知道sum数组里面有n个元素,又因为它们都不能被n整除,那么我们可以得到以下信息:任意的(sum[i] %n)都非0且结果都在(1到n-1范围里面)

                  这样的话--> n个结果在  1到n-1 范围内,必然存在两个相等的结果。而这两个相同结果所对应的sum[] 之差 必定能被 n整除。

 

证毕。

 

对于抽屉原理,可以有以下拓展:(1) 数列里面元素个数只要大于或者等于n也成立 (2) 找到的 若干个数 不是连续的也成立。

 

转自:https://blog.csdn.net/chenzhenyu123456/article/details/46458991

这篇关于容斥原理+欧拉函数+抽屉原理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/891828

相关文章

【操作系统】信号Signal超详解|捕捉函数

🔥博客主页: 我要成为C++领域大神🎥系列专栏:【C++核心编程】 【计算机网络】 【Linux编程】 【操作系统】 ❤️感谢大家点赞👍收藏⭐评论✍️ 本博客致力于知识分享,与更多的人进行学习交流 ​ 如何触发信号 信号是Linux下的经典技术,一般操作系统利用信号杀死违规进程,典型进程干预手段,信号除了杀死进程外也可以挂起进程 kill -l 查看系统支持的信号

java中查看函数运行时间和cpu运行时间

android开发调查性能问题中有一个现象,函数的运行时间远低于cpu执行时间,因为函数运行期间线程可能包含等待操作。native层可以查看实际的cpu执行时间和函数执行时间。在java中如何实现? 借助AI得到了答案 import java.lang.management.ManagementFactory;import java.lang.management.Threa

SQL Server中,isnull()函数以及null的用法

SQL Serve中的isnull()函数:          isnull(value1,value2)         1、value1与value2的数据类型必须一致。         2、如果value1的值不为null,结果返回value1。         3、如果value1为null,结果返回vaule2的值。vaule2是你设定的值。        如

tf.split()函数解析

API原型(TensorFlow 1.8.0): tf.split(     value,     num_or_size_splits,     axis=0,     num=None,     name='split' ) 这个函数是用来切割张量的。输入切割的张量和参数,返回切割的结果。  value传入的就是需要切割的张量。  这个函数有两种切割的方式: 以三个维度的张量为例,比如说一

数据库原理与安全复习笔记(未完待续)

1 概念 产生与发展:人工管理阶段 → \to → 文件系统阶段 → \to → 数据库系统阶段。 数据库系统特点:数据的管理者(DBMS);数据结构化;数据共享性高,冗余度低,易于扩充;数据独立性高。DBMS 对数据的控制功能:数据的安全性保护;数据的完整性检查;并发控制;数据库恢复。 数据库技术研究领域:数据库管理系统软件的研发;数据库设计;数据库理论。数据模型要素 数据结构:描述数据库

计算机组成原理——RECORD

第一章 概论 1.固件  将部分操作系统固化——即把软件永恒存于只读存储器中。 2.多级层次结构的计算机系统 3.冯*诺依曼计算机的特点 4.现代计算机的组成:CPU、I/O设备、主存储器(MM) 5.细化的计算机组成框图 6.指令操作的三个阶段:取指、分析、执行 第二章 计算机的发展 1.第一台由电子管组成的电子数字积分和计算机(ENIAC) 第三章 系统总线

GaussDB关键技术原理:高性能(二)

GaussDB关键技术原理:高性能(一)从数据库性能优化系统概述对GaussDB的高性能技术进行了解读,本篇将从查询处理综述方面继续分享GaussDB的高性能技术的精彩内容。 2 查询处理综述 内容概要:本章节介绍查询端到端处理的执行流程,首先让读者对查询在数据库内部如何执行有一个初步的认识,充分理解查询处理各阶段主要瓶颈点以及对应的解决方案,本章以GaussDB为例讲解查询执行的几个主要阶段

神经网络第三篇:输出层及softmax函数

在上一篇专题中,我们以三层神经网络的实现为例,介绍了如何利用Python和Numpy编程实现神经网络的计算。其中,中间(隐藏)层和输出层的激活函数分别选择了 sigmoid函数和恒等函数。此刻,我们心中不难发问:为什么要花一个专题来介绍输出层及其激活函数?它和中间层又有什么区别?softmax函数何来何去?下面我们带着这些疑问进入本专题的知识点: 1 输出层概述 2 回归问题及恒等函数 3

神经网络第一篇:激活函数是连接感知机和神经网络的桥梁

前面发布的文章介绍了感知机,了解了感知机可以通过叠加层表示复杂的函数。遗憾的是,设定合适的、能符合预期的输入与输出的权重,是由人工进行的。从本章开始,将进入神经网络的学习,首先介绍激活函数,因为它是连接感知机和神经网络的桥梁。如果读者认知阅读了本专题知识,相信你必有收获。 感知机数学表达式的简化 前面我们介绍了用感知机接收两个输入信号的数学表示如下:

XMG 抽屉效果

1.比如说我创建了3个View -(void)viewDidLoad{  [ super viewDidLoad]; [self setUpChild] ;         UIPanGestureRecognizer *pan=[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(pan:)];