能被整除的数

简介: 能被整除的数

题目描述

给定一个整数 nn 和 mm 个不同的质数 p1p1, p2p2,…, pmpm。

请你求出 11 ~ nn 中能被 p1p1, p2p2,…, pmpm 中的至少一个数整除的整数有多少个。

算法

容斥原理

记 11 ~ nn 所有数的集合为 AA。设性质 PiPi 为:nn 可以被质数 pipi整除。设 11 ~ nn 中满足性质 PiPi 的数所在的集合为 AiAi,集合大小记为 |Ai||Ai|。至少满足 P1P1, P2P2, …, PmPm 这些性质中至少一个性质的数所在集合显然为

A1∪A2∪…∪Am

A1∪A2∪…∪Am

,则由容斥原理,这个集合的大小为:

|A1∪A2∪…∪Am|=∑i=1m|Ai|−∑1~m 的2组合|Ai∩Aj|+∑1~m 的3组合|Ai∩Aj∩Ak|+…+(−1)m−1|A1∩A2∩…∩Am|

|A1∪A2∪…∪Am|=∑i=1m|Ai|−∑1~m 的2组合|Ai∩Aj|+∑1~m 的3组合|Ai∩Aj∩Ak|+…+(−1)m−1|A1∩A2∩…∩Am|

对于本题,如果一个数满足多个性质,即可以同时被 pi1,pi2,…,pikpi1,pi2,…,pik整除,则这样的数共有

⌊npi1pi2…pik⌋

⌊npi1pi2…pik⌋

个。因此,问题就回到了给定 mm 个质数构成的集合 { p1p1, p2p2,…, pmpm },这个集合的所有非空子集。

深度优先搜索实现集合非空子集枚举

将这 mm 个数放入数组 pp 中,下标范围为 00 ~ m−1m−1,则问题转化为枚举集合 { 0,1,…,m−10,1,…,m−1 } 所有的非空子集。参考 AcWing 842. 排列数字 ,本题也可以用深度优先搜索。但与排列数字那道题不同的是,一串数字的多个排列有可能对应于一个子集。例如:1 2 3 4 5 和 1 3 2 5 4这两个排列对应于同一个子集 {1,2,3,4,51,2,3,4,5}。因此,为了避免深度优先搜索的时候出现重复搜索的情况,我们规定搜索的序列必须是单调递增的,即后面搜索到的数必须比前面的数大,这样就能避免因数字的排列引起的重复。例如,在之前的搜索我们得到的结果是 0 1 3 4,那么现在搜索的数的范围(即第 5 个数)必须从 5 开始,排列为 0 1 3 4 5 或 0 1 3 4 6 或 0 1 3 4 7 等等。

下面用归纳法证明上述算法的正确性。对于一个组合序列 x1,x2,…,xkx1,x2,…,xk,其中 x1<x2<…<xkx1<x2<…<xk。在第一个数的搜索我们会遍历所有的数,因此 x1x1 一定会被搜到,因此序列中的 x1x1 可以被搜到。假设 x1,x2,…,xi−1x1,x2,…,xi−1可以这个序列可以成功搜索,由于 xi>xi−1xi>xi−1,因此xixi也可以被搜到,所以序列 x1,x2,…,xi−1,xix1,x2,…,xi−1,xi一定会被搜到。因此归纳可得,任意一个组合序列都能被搜索到。

对于每次的搜索,我们需要直到上一级的乘积结果 times,即 pi1pi2…pik−1pi1pi2…pik−1。那么,对于本次搜索到的pikpik,直接乘上之前的乘积,得到新的乘积 new_times,便可算出容斥原理中的新的项 n/(pi1pi2…pik−1)n/(pi1pi2…pik−1),并据此修改结果变量 res. 但是,应该是加还是减呢?因此,我们还要从上一层接受操作数 op(等于+1或-1)。如果上一层操作数是op,那么传到这层的一定是 -op。这样,结果变量就被修改为 res += op * n / new_times

C++ 代码

/**
• 本质是组合枚举问题,详见自己写的题解
*/
#include
using namespace std;
typedef long long LL;
const int M = 20;
int n, m;
int p[M];
/**
• s: 当前允许搜索的最小下标
• times: 前面的质数乘积。注意times变量的类型要取成long long,因为乘积有可能溢出
• op: 操作数,取+1或-1
• res: 保存最终结果的变量,由于此变量被引用,因此可以实时被修改
*/
void dfs(int s, LL times, int op, int &res) {
for (int i = s; i < m; i++) {
LL new_times = times * p[i]; // 前面的乘积结果乘上这个质数的到新的乘积
res += op * (n / new_times); // 将新的项加到结果上
dfs(i + 1, new_times, -op, res); // 之后的数从i+1开始搜索,传递乘上pi后的新乘积,并将op取反
}
}
int main() {
scanf(“%d%d”, &n, &m);
for (int i = 0; i < m; i++) scanf(“%d”, p + i);
int res = 0;
dfs(0, 1, 1, res);
printf("%d", res);
return 0

}

求乘法逆元

定义:即已知 bb 与 mm 互质 且 b|ab|a 则求一个xx 使得 a/b≡a∗xmodma/b≡a∗xmodm

[注] 简单定义 即 b∗x≡1modmb∗x≡1modm 且 bb 与 mm 互质 则 xx 为 bb 的逆元

  1. 当mm为质数时
    求解过程如下 :

费马小定理可知

bm−1≡1modm

bm−1≡1modm

a/b≡a∗xmodm

a/b≡a∗xmodm

联立以上两式,得:

a/b∗bm−1≡a∗xmodm

a/b∗bm−1≡a∗xmodm

即为

a∗bm−2≡a∗xmodm

a∗bm−2≡a∗xmodm

而b|ab|a,且bb与m互质,因此对于bb来说,一定存在一个aa也与mm互质,故而aa可以在两边同时约去(感谢yxc大佬)

因此

x≡bm−2modm

x≡bm−2modm

无解条件 即 bb与mm不互质时无解,而mm为质数,所以bb只能为mm的倍数,此时无解,也就是b%m0b%m0

2.当m不是质数时,则需要用扩展欧几里得求逆元

3.逆元的作用

当 a,ba,b 很大时 求 a/bmodpa/bmodp 的值

而 a/bmodp≠((amodp)/(bmodp))modpa/bmodp≠((amodp)/(bmodp))modp

因此可以借助逆元转化为乘法,再算,设b的逆元为b−1b−1

则 a/bmodp=a∗b−1modp=((amodp)∗(b−1modp))modpa/bmodp=a∗b−1modp=((amodp)∗(b−1modp))modp

当m为质数时,求解逆元的C++代码如下

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int qmi(int a, int b, int p){//快速幂
int res = 1%p;
while(b){
if(b&1) res = (LL)resa%p;
a = (LL)aa%p;
b>>=1;
}
return res;
}
int main(){
int n,a,p;
cin>>n;
while(n–){
cin>>a>>p;//p是质数 求 a的逆元(mod p意义下)
if(a%p) cout<<qmi(a,p-2,p)<<endl;
else cout<<“impossible”<<endl;
}
return 0


相关文章
|
2月前
|
监控 Linux
Linux系统监控报告CPU软锁定问题(soft lockup)诊断方法
以上方法结合起来使用将大大提高解决此类问题效率与成功率。实际操作过程需谨慎考虑当前环境与场景特点选择合适方法,并且要注意数据备份与恢复计划防止误操作造成不可挽回损失。
391 13
|
8月前
|
JSON NoSQL MongoDB
微服务——MongoDB常用命令——文档基本CRUD
本文介绍了MongoDB中文档的基本操作,包括插入、查询、更新和删除。单个文档插入使用`insert()`或`save()`方法,批量插入用`insertMany()`。查询所有文档用`find()`,条件查询可在`find()`中添加参数,投影查询控制返回字段。更新文档通过`update()`实现,支持覆盖修改、局部修改(使用`$set`)和批量修改。列值增长可用`$inc`实现。删除文档用`remove()`,需谨慎操作以免误删数据。此外,文档键值对有序,区分大小写,不能有重复键。
166 1
|
6月前
|
人工智能
使用CodeBuddy实现网页自动连点器
CodeBuddy 能够迅速理解复杂功能要求,精准生成自动连点器代码。无论是游戏场景里对技能释放点击频率的精确控制,还是办公场景中对特定单元格点击位置的灵活设定,它都能高效满足。
165 6
|
12月前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台策略
在移动应用开发的战场上,安卓和iOS两大阵营各据一方。随着技术的演进,跨平台开发框架成为开发者的新宠,旨在实现一次编码、多平台部署的梦想。本文将探讨跨平台开发的优势与挑战,并分享实用的开发技巧,帮助开发者在安卓和iOS的世界中游刃有余。
|
8月前
|
编解码 人工智能 测试技术
CogView4:智谱开源中文文生图新标杆,中文海报+任意分辨率一键生成
CogView4 是智谱推出的开源文生图模型,支持中英双语输入和任意分辨率图像生成,特别优化了中文文字生成能力,适合广告、创意设计等场景。
416 1
CogView4:智谱开源中文文生图新标杆,中文海报+任意分辨率一键生成
|
8月前
|
存储 NoSQL 定位技术
MongoDB索引知识
MongoDB索引是提升查询性能的关键工具,通过构建特殊的数据结构(如B树)优化数据访问路径。无索引时,查询需全集合扫描,时间复杂度为O(n);使用索引后可降至O(log n),实现毫秒级响应。MongoDB支持多种索引类型:单字段索引适用于高频单字段查询;复合索引基于最左前缀原则优化多条件过滤和排序;专业索引包括地理空间索引(支持LBS服务)、文本索引(全文搜索)和哈希索引(分片键优化)。合理选择和优化索引类型,可显著提升数据库性能。建议使用explain()分析查询计划,并定期清理冗余索引。
|
11月前
|
人工智能 文字识别 API
|
9月前
|
人工智能 负载均衡 数据可视化
阿里云百炼免费0元部署DeepSeek-R1满血版,替大家试过了,3分钟部署成功!
阿里云百炼平台提供免费100万Token,一键部署DeepSeek-R1满血版仅需3分钟。新手无需编码,最低0元即可体验。平台支持自动弹性扩展,保障API调用稳定性,并提供Chatbox客户端简化操作流程。详情及教程见阿里云百炼官网。
434 4
|
10月前
|
文字识别 开发者 数据处理
多模态数据信息提取解决方案评测报告!
阿里云推出的《多模态数据信息提取》解决方案,利用AI技术从文本、图像、音频和视频中提取关键信息,支持多种应用场景,大幅提升数据处理效率。评测涵盖部署体验、文档清晰度、模板简化、示例验证及需求适配性等方面。方案表现出色,部署简单直观,功能强大,适合多种业务场景。建议增加交互提示、多语言支持及优化OCR和音频转写功能...
327 3
多模态数据信息提取解决方案评测报告!
关于流控RTS/CTS ,DTR/DSR的说明
关于流控RTS/CTS ,DTR/DSR的说明
2912 0