当前位置: 首页 > news >正文

数据结构与算法学习笔记----容斥原理

数据结构与算法学习笔记----容斥原理

@@ author: 明月清了个风
@@ first publish time: 2025.1.30

ps⭐️介绍了容斥原理的相关内容以及一道对应的应用例题。


Acwing 890. 能被整除的数

[原题链接](890. 能被整除的数 - AcWing题库)

给定一个整数 n n n m m m个不同的质数 p 1 , p 2 , ⋯ , p m p_1,p_2,\cdots,p_m p1,p2,,pm

请你求出 1 ∼ n 1 \sim n 1n中能被 p 1 , p 2 , ⋯ , p m p_1,p_2,\cdots,p_m p1,p2,,pm中的至少一个数整除的整数有多少个。

输入格式

第一行包含整数 n n n m m m

第二行包含 m m m个质数。

输出格式

输出一个整数,表示满足条件的整数的个数。

数据范围

1 ≤ m ≤ 16 1 \le m \le 16 1m16,

1 ≤ n , p i ≤ 1 0 9 1 \le n, p_i \le 10^9 1n,pi109

思路

容斥原理是一种重要的组合数学方法,用于解决多个集合的元素计数问题。它的核心思想是通过对集合进行交集与并集的操作,减去重复计算的部分,从而准确地计算出多个集合的并集中元素的总数。

  1. 两个集合的容斥原理

A A A B B B是两个集合,则它们的并集 A ∪ B A \cup B AB的元素个数为:

∣ A ∪ B ∣ = ∣ A ∣ + ∣ B ∣ − ∣ A ∩ B ∣ |A \cup B| = |A| + |B| - |A \cap B| AB=A+BAB

其中, ∣ A ∣ |A| A ∣ B ∣ |B| B分别是集合 A A A B B B的元素个数, ∣ A ∩ B ∣ |A \cap B| AB是集合 A A A B B B的交集的元素个数。

  1. 三个集合的容斥原理

A A A B B B C C C是三个集合,则它们的并集 A ∪ B ∪ C A \cup B \cup C ABC的元素个数为:

∣ A ∪ B ∪ C ∣ = ∣ A ∣ + ∣ B ∣ + ∣ C ∣ − ∣ A ∩ B ∣ − ∣ B ∩ C ∣ − ∣ C ∩ A ∣ + ∣ A ∩ B ∩ C ∣ |A \cup B \cup C| = |A| + |B| + |C| - |A \cap B| - |B \cap C| - |C \cap A| + |A \cap B \cap C| ABC=A+B+CABBCCA+ABC

其中, ∣ A ∣ |A| A ∣ B ∣ |B| B ∣ C ∣ |C| C分别是集合 A A A B B B C C C的元素个数, ∣ A ∩ B ∣ |A \cap B| AB ∣ B ∩ C ∣ |B \cap C| BC ∣ C ∩ A ∣ |C \cap A| CA分别是集合 A A A B B B B B B C C C C C C A A A的交集的元素个数, ∣ A ∩ B ∩ C ∣ |A \cap B \cap C| ABC是集合 A A A B B B C C C的交集的元素个数。

  1. n n n个集合的容斥原理

A 1 , A 2 , … , A n A_1, A_2, \ldots, A_n A1,A2,,An n n n个集合,则它们的并集 A 1 ∪ A 2 ∪ … ∪ A n A_1 \cup A_2 \cup \ldots \cup A_n A1A2An的元素个数为:

∣ A 1 ∪ A 2 ∪ … ∪ A n ∣ = ∑ i = 1 n ∣ A i ∣ − ∑ 1 ≤ i < j ≤ n ∣ A i ∩ A j ∣ + ∑ 1 ≤ i < j < k ≤ n ∣ A i ∩ A j ∩ A k ∣ − ⋯ + ( − 1 ) n − 1 ∣ A 1 ∩ A 2 ∩ … ∩ A n ∣ |A_1 \cup A_2 \cup \ldots \cup A_n| = \sum_{i=1}^{n} |A_i| - \sum_{1 \leq i < j \leq n} |A_i \cap A_j| + \sum_{1 \leq i < j < k \leq n} |A_i \cap A_j \cap A_k| - \cdots + (-1)^{n-1} |A_1 \cap A_2 \cap \ldots \cap A_n| A1A2An=i=1nAi1i<jnAiAj+1i<j<knAiAjAk+(1)n1A1A2An

其中,求和符号表示对所有可能的集合组合进行求和, ( − 1 ) n − 1 (-1)^{n-1} (1)n1表示当集合的交集数量(即下标集合的大小)为奇数时取正号,为偶数时取负号。

对于 n n n个集合的容斥原理公式来说,最后共有 2 n 2^n 2n项,因为每一项都可以看做是一个组合数,比如 ∑ i = 1 n ∣ A i ∣ \sum_{i=1}^{n}|A_i| i=1nAi中共有是 n n n项,因为相当于 C n 1 C_{n}^{1} Cn1种方案数;对于 ∑ 1 ≤ i < j ≤ n ∣ A i ∩ A j ∣ \sum_{1 \leq i < j \leq n} |A_i \cap A_j| 1i<jnAiAj也同样是这样,相当于 C n 2 C_{n}^{2} Cn2种方案数;那么所有的项目就相当于 C n 1 + C n 2 + C n 3 + ⋯ + C n n = 2 n − 1 C_n^{1} + C_n^{2} + C_n^{3} + \cdots + C_n^{n} = 2^n - 1 Cn1+Cn2+Cn3++Cnn=2n1项,但是其实所有集合都不选也是一项,也就是 C n 0 C_n^0 Cn0,只是没有显式的计算他,因此最开始说共有 2 n 2^n 2n项。

y总还讲了另外一个等式,这个式子表明了容斥原理的核心思想:每个元素只被统计一次
C k 1 − C k 2 + C k 3 − … + ( − 1 ) k + 1 C k k = 1 C_{k}^{1} - C_{k}^{2} + C_{k}^{3} - \ldots + (-1)^{k+1}C_{k}^{k} = 1 Ck1Ck2+Ck3+(1)k+1Ckk=1
这个等式表明,在容斥原理的交替求和公式中,每个元素在所有可能的集合组合(交集)中出现的次数,经过正负交替相加后,总和等于1,从而确保了每个元素在最终的计算中只被统计了一次。

这里再回到题目来看,我们需要统计 1 ∼ n 1 \sim n 1n中至少被一个所给的数整除的数有多少个,也就是说如果一个数能被好几个数整除,也只统计一次,如果我们用暴力做法,需要对 n n n个数都遍历 m m m个数对比,时间复杂度为 O ( n ⋅ m ) O(n \cdot m) O(nm)会超时,但是我们使用容斥原理进行统计的话,就能将时间复杂度降低到 O ( 2 m ) O(2^m) O(2m)

首先,对于每一个给出的质数p_i,都会有一个集合表示所有能被他整除的数,要关注的是这个集合中元素的个数,而不是这些数是哪些数。这个数量我们可以通过 ⌊ n p i ⌋ \lfloor \frac{n}{p_i} \rfloor pin计算得出,同样的对于同时是多个质数的倍数的集合中元素的个数也可以这样计算得到,例如 ⌊ n p i p j ⌋ \lfloor \frac{n}{p_i p_j} \rfloor pipjn的形式,我们可以通过这样的方式处理出所有集合包含元素的个数。

然后,通过对上面n个元素对应的容斥原理计算公式进行观察可以发现,当一个元素被包含在偶数个集合中时,那就应该减去,集合数为奇数时加上,同样用上面的来举例,所有的只被一个质数整除的元素集合的数目 ⌊ n p i ⌋ \lfloor \frac{n}{p_i} \rfloor pin都应该被加到答案 r e s res res中区,所有被两个质数整除的元素集合的数目 ⌊ n p i p j ⌋ \lfloor \frac{n}{p_i p_j} \rfloor pipjn都应该从答案中减去。

至此,题目的思路已经理清了,需要考虑的是代码的逻辑,我们要统计的有两个东西

  1. 所有集合的大小。
  2. 每个集合是能被几个质数整除。

这里就用到了上面对于容斥原理公式包含项数的结果了,一共 2 m − 1 2^m - 1 2m1项,一共有 m m m个质数,那么我们可以通过统计 1 ∼ 2 m 1 \sim 2^m 12m,一共 2 m − 1 2^m - 1 2m1个数代表所有的集合,每个数的二进制表示中的 1 1 1的数量表示这个集合是被几个质数整除的,同时,集合的大小可以在这个过程中同时处理出来,将所有质数存在数组p[N]中,记录一个数t = 1,当第i位为1时,就将t *= p[i],遍历完这个数的二进制的所有位后,通过num = n / t得到该集合的大小,具体的看代码吧

代码

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>using namespace std;typedef long long LL;const int N = 20;int p[N];
int n, m;int main()
{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, cnt = 0;for(int j = 0; j < m; j ++){if(i >> j & 1){if((LL)t * p[j] > n){t = -1;break;}t *= p[j];cnt ++;}}if(t == -1) continue;if(cnt % 2) res += n / t;else res -= n / t;}cout << res << endl;return 0;
}

相关文章:

数据结构与算法学习笔记----容斥原理

数据结构与算法学习笔记----容斥原理 author: 明月清了个风 first publish time: 2025.1.30 ps⭐️介绍了容斥原理的相关内容以及一道对应的应用例题。 Acwing 890. 能被整除的数 [原题链接](890. 能被整除的数 - AcWing题库) 给定一个整数 n n n和 m m m个不同的质数 p 1 …...

Java 知识速记:全面解析 final 关键字

Java 知识速记&#xff1a;全面解析 final 关键字 什么是 final 关键字&#xff1f; final 关键字是 Java 中的一个修饰符。它可以用于类、方法和变量&#xff0c;其作用是限制对这些元素的修改。究竟如何限制&#xff1f;我们来逐个分析。 final 在变量中的用法 1. 声明常…...

(笔记+作业)书生大模型实战营春节卷王班---L0G2000 Python 基础知识

学员闯关手册&#xff1a;https://aicarrier.feishu.cn/wiki/QtJnweAW1iFl8LkoMKGcsUS9nld 课程视频&#xff1a;https://www.bilibili.com/video/BV13U1VYmEUr/ 课程文档&#xff1a;https://github.com/InternLM/Tutorial/tree/camp4/docs/L0/Python 关卡作业&#xff1a;htt…...

9、Docker环境安装Nginx

一、拉取镜像 docker pull nginx:1.24.0二、创建映射目录 作用&#xff1a;是将docker中nginx的相关配置信息映射到外面&#xff0c;方便修改配置文件 1、创建目录 # cd home/ # mkdir nginx/ # cd nginx/ # mkdir conf html log2、生成容器 docker run -p 80:80 -d --name…...

受击反馈HitReact、死亡效果Death Dissolve、Floating伤害值Text(末尾附 客户端RPC )

受击反馈HitReact 设置角色受击标签 (GameplayTag基本了解待补充) 角色监听标签并设置移动速度 创建一个受击技能&#xff0c;并应用GE 实现设置角色的受击蒙太奇动画 实现角色受击时播放蒙太奇动画&#xff0c;为了保证通用性&#xff0c;将其设置为一个函数&#xff0c;并…...

572. 另一棵树的子树

前导题&#xff1a;100. 相同的树 回顾一下 判断两棵二叉树相同&#xff0c;根结点相同 且 左子树相同 且 右子树相同。 于是判断如下&#xff1a; 根结点都为null&#xff0c;返回true根结点不都为null&#xff0c;返回false根结点都不为null&#xff0c;但是值不相同&#…...

MATLAB中textBoundary函数用法

目录 语法 说明 示例 匹配文本的边界 匹配文本的结尾边界 对文本的边界求反 textBoundary函数的功能是匹配文本的开头或结尾。 语法 pat textBoundary pat textBoundary(type) 说明 pat textBoundary 创建与文本开头或结尾匹配的模式。textBoundary 可以使用 ~ 运算…...

vue3的路由配置

先找到Layout布局文件&#xff0c;从中找到左侧边栏&#xff0c;找到下述代码 <SidebarItem v-for"route in noHiddenRoutes" :key"route.path" :item"route" :base-path"route.path" />/** *菜单项 <SidebarItem>: *使用…...

在彼此的根系里呼吸

爱如草木&#xff0c;需以晨露滋养&#xff0c;而非绳索捆缚。一段健康的亲密关系&#xff0c;恰似两株根系相连却各自向阳的树——风起时枝叶相触&#xff0c;晴空下共享光影&#xff0c;却始终保有向地心深处生长的自由。那些纠缠的根须是信任编织的网&#xff0c;容得下沉默…...

深入理解若依RuoYi-Vue数据字典设计与实现

深入理解若依数据字典设计与实现 一、Vue2版本主要文件目录 组件目录src/components&#xff1a;数据字典组件、字典标签组件 工具目录src/utils&#xff1a;字典工具类 store目录src/store&#xff1a;字典数据 main.js&#xff1a;字典数据初始化 页面使用字典例子&#xf…...

深入MapReduce——从MRv1到Yarn

引入 我们前面篇章有提到&#xff0c;和MapReduce的论文不太一样。在Hadoop1.0实现里&#xff0c;每一个MapReduce的任务并没有一个独立的master进程&#xff0c;而是直接让调度系统承担了所有的worker 的master 的角色&#xff0c;这就是Hadoop1.0里的 JobTracker。在Hadoop1…...

Flutter_学习记录_Tab的简单Demo~真的很简单

1. Tab的简单使用了解 要实现tab(选项卡或者标签视图)需要用到三个组件&#xff1a; TabBarTabBarViewTabController 这一块&#xff0c;我也不知道怎么整理了&#xff0c;直接提供代码吧&#xff1a; import package:flutter/material.dart;void main() {runApp(MyApp());…...

CSS核心

CSS的引入方式 内部样式表是在 html 页面内部写一个 style 标签&#xff0c;在标签内部编写 CSS 代码控制整个 HTML 页面的样式。<style> 标签理论上可以放在 HTML 文档的任何地方&#xff0c;但一般会放在文档的 <head> 标签中。 <style> div { color: r…...

Deepseek本地部署(ollama+open-webui)

ollama 首先是安装ollama&#xff0c;这个非常简单 https://ollama.com/ 下载安装即可 open-webui 这个是为了提供一个ui&#xff0c;毕竟我们也不想在cmd和模型交互&#xff0c;很不方便。 第一&#xff0c;需要安装python3.11&#xff0c;必须是3.11&#xff08;其他版…...

PaddleSeg 从配置文件和模型 URL 自动化运行预测任务

git clone https://github.com/PaddlePaddle/PaddleSeg.git# 在ipynb里面运行 cd PaddleSegimport sys sys.path.append(/home/aistudio/work/PaddleSeg)import os# 配置文件夹路径 folder_path "/home/aistudio/work/PaddleSeg/configs"# 遍历文件夹&#xff0c;寻…...

数据结构 队列

目录 前言 一&#xff0c;队列的基本知识 二&#xff0c;用数组实现队列 三&#xff0c;用链表实现队列 总结 前言 接下来我们将学习队列的知识&#xff0c;这会让我们了解队列的基本概念和基本的功能 一&#xff0c;队列的基本知识 (Queue) 我们先来研究队列的ADT&#xff0c…...

Cocoa和Cocoa Touch是什么语言写成的?什么是Cocoa?编程语言中什么是框架?为什么苹果公司Cocoa类库有不少NS前缀?Swift编程语言?

Cocoa和Cocoa Touch是什么语言写成的? 二者主要都是用Objective-C语言编写而成的。 什么是Cocoa? Cocoa是苹果操作系统macOS和iOS上的应用程序开发框架集合&#xff0c;核心语言是Objective-C编程语言&#xff0c;在移动平台被称为Cocoa Touch&#xff0c;Cocoa包含多个子框架…...

登录管理——认证方案(JWT、拦截器、ThreadLocal、短信验证)

两种常见的认证方案 基于Session认证 登录状态信息保存在服务器内存中&#xff0c;若访问量增加&#xff0c;单台节点压力会较大集群环境下需要解决集群中的各种服务器登录状态共享问题 解决方案&#xff1a;将登录状态保存的Redis中&#xff0c;从Redis中查找登录状态 基于…...

Java实现LFU缓存策略实战

LFU算法原理在Java中示例实现集成Caffeine的W-TinyLFU策略缓存实战总结LFU与LRU稍有不同,LFU是根据数据被访问的频率来决定去留。尽管它考虑了数据的近期使用,但它不会区分数据的首次访问和后续访问,淘汰那些访问次数最少的数据。 这种缓存策略主要用来处理以下场景: 数据…...

物业系统改革引领行业智能化管理与提升服务质量的新征程

内容概要 在当今迅速变化的社会中&#xff0c;物业系统改革正在悄然推动行业的智能化管理进程。物业管理作为一个古老而传统的领域&#xff0c;面临着诸多挑战&#xff0c;包括效率低下、业主需求难以满足等。数字化转型为这一现象注入了新活力&#xff0c;帮助物业公司通过先…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

golang循环变量捕获问题​​

在 Go 语言中&#xff0c;当在循环中启动协程&#xff08;goroutine&#xff09;时&#xff0c;如果在协程闭包中直接引用循环变量&#xff0c;可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下&#xff1a; 问题背景 看这个代码片段&#xff1a; fo…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

作为测试我们应该关注redis哪些方面

1、功能测试 数据结构操作&#xff1a;验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化&#xff1a;测试aof和aof持久化机制&#xff0c;确保数据在开启后正确恢复。 事务&#xff1a;检查事务的原子性和回滚机制。 发布订阅&#xff1a;确保消息正确传递。 2、性…...

【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error

在前端开发中&#xff0c;JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作&#xff08;如 Promise、async/await 等&#xff09;&#xff0c;开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝&#xff08;r…...

LangFlow技术架构分析

&#x1f527; LangFlow 的可视化技术栈 前端节点编辑器 底层框架&#xff1a;基于 &#xff08;一个现代化的 React 节点绘图库&#xff09; 功能&#xff1a; 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...