不与V互质的最大数
Maximum number not coprime to V
给定N个整数的固定数组a,其中N<100000,并且阵列的所有元素也小于或等于100000。A中的数字不是单调增加的、连续的或以其他方式方便地组织的。
现在,我得到了多达100000个形式为{V,L,R}的查询,其中在每个查询中,我需要找到最大的数A[I],其中I在与给定值V不互质的范围[L,R]中。(也就是说,GCD(V,A[I](不等于1。(
如果这是不可能的,那么也要告诉在给定范围内的所有数字都是V的互质。
一种基本方法是从L和R之间的每个A[i]迭代,并用值V计算GCD,从而找到最大值。但是,如果查询数量也可以达到100000,还有更好的方法吗。在这种情况下,每次检查每个数字的效率太低了。
示例:
- 设N=6,数组为[1,2,3,4,5,4],设V为2,范围[L,R]为[2,5]
- 那么答案是4
说明:
GCD(2,2)=2
GCD(2,3)=1
GCD(2,4)=2
GCD(2,5)=1
所以这里的最大值是4。
由于您有一个大数组,但只有一个V
,因此从分解V
开始应该会更快。在那之后,你的互质测试变成了简单地求取V
的每个唯一因子的余数。
Daniel Bernstein的《在本质上线性的时间内分解成协时》(Journal of Algorithms 54:1,1-30(2005((回答了一个类似的问题,并被Nadia Heninger的《新研究:无需恐慌可分解密钥——只需注意你的Ps和Qs》用于识别坏的(重复因子(RSA模。这里的问题是在一组非常大的数字之间找到共同的因子,而不是一次一对。
假设
V = p_1*...*p_n
其中p_i是素数(您可以将其限制为不同素数(。现在答案是
result = -1
for p_i:
res = floor(R / p_i) * p_i
if res >= L and res > result:
result = res
因此,如果你能快速分解V
,那么这将是非常有效的。
EDIT我没有注意到数组不必包含所有整数。在这种情况下,对其进行筛选,即给定素数p_1。。。,p_n创建一个"反向"筛(即范围[L, R]
中素数的所有倍数(。然后你可以把这个筛子和你的初始数组做一个交集。
EDIT2要生成所有倍数的集合,可以使用以下算法:
primes = [p_1, ..., p_n]
multiples = []
for p in primes:
lower = floor(L / p)
upper = floor(R / p)
for i in [lower+1, upper]:
multiples.append(i*p)
重要的是,从数学上得出,V
与不在multiples
中的[L, R]
范围内的每个数是互素的。现在您只需执行:
solution = -1
for no in initial_array:
if no in multiples:
solution = max(solution, no)
请注意,如果将result
实现为一个集合,则if no in result:
检查为O(1)
。
示例假设V = 6 = 2*3
和initial_array = [7,11,12,17,21]
以及L=10
和R=22
。让我们从倍数开始。根据算法,我们得到
multiples = [10, 12, 14, 16, 18, 20, 22, 12, 15, 18, 21]
前7个是2的倍数(在[10,22]范围内(,后4个是3的倍数(位于[10,2]范围内(。由于我们处理的是集合(std::set
?(,因此不会有重复(12和18(:
multiples = [10, 12, 14, 16, 18, 20, 22, 15, 21]
现在浏览initial_array
并检查multiples
中的值。我们得到最大的这样的数字是CCD_ 19。事实上,CCD_ 20与CCD_。
对A的每个元素进行因子运算,并为每个可能的素因子存储包含该因子的数字的排序列表。
给定一个数n包含O(logn(素数,该列表将使用O(nlogN(内存。
然后,对于每个查询(V,L,R(,搜索V中的每个素因子,在[L,R]中包含该因子的最大数是多少(这可以通过简单的二进制搜索来完成(。
- 为什么常量词在重载运算符中不与 ostream 对象一起使用<<?
- Chilkat SFTP 文件修改时间不与上传更新
- 为什么重复的空基存储不与 vtable 指针重叠?
- 为什么重载运算符不与 std::string 一起使用 msvc /MD 标志
- 找到不大于 A 的最大数的最有效方法,该数可被 B 整除
- C++:最大数组值函数工作不正常
- 当它们不与GCC和CMAKE一起使用时,如何解析未定义的引用
- lpCmdLine 不与字符串进行比较
- 在浮点数32中保存浮点数16最大数
- find_if不与const_iterator合作
- 使用 DP 的非相邻元素的最大数组总和
- mkdir()不与绝对filepath一起使用
- OpenGL Glulookat不与着色器一起使用
- 键盘输入不与WebAssembly和Emscripten配合使用
- 快板不与克里昂合作(0xC000007B)
- 使用scanf()在数组中获取字符(不与空格分开)
- CMAKE:为什么CMAKE_CXX_STANDARD似乎不与check_cxx_source_compiles合作
- 如何在不与标准库运算符冲突的情况下为一组相关类重载运算符?
- 在任意加长的集合中查找最大数不起作用
- 不与V互质的最大数