总结与思考:数论分块

本文探讨了数论分块的概念,分析了当1≤i≤⌊n⌋时,⌊in⌋的不同数值个数不超过2n。通过具体例子阐述了数论分块的性质,包括块的右端下标与f(i)值域的关系,以及当x≤⌊n⌋时,f(x)的值严格单调增的结论。此外,文章提到了在算法设计中利用数论分块优化存储和访问策略,以提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于⌊ni⌋\lfloor \frac{n}{i} \rfloorin的值域大小

1≤i≤⌊n⌋1 \le i \le \lfloor \sqrt n \rfloor1in时,⌊ni⌋\lfloor \frac{n}{i} \rfloorin的不同数值个数显然是不超过⌊n⌋\lfloor \sqrt n \rfloorn

⌊n⌋<i≤n\lfloor \sqrt n \rfloor < i \le nn<in时,因为1≤⌊ni⌋≤n1 \le \lfloor \frac{n}{i} \rfloor \le \sqrt n1inn,所以不同数值个数还是不超过⌊n⌋\lfloor \sqrt n \rfloorn

综合上述两种情况,⌊ni⌋\lfloor \frac{n}{i} \rfloorin的不同数值个数严格不大于2n2 \sqrt n2n

数论分块的相关概念

“数论分块”这个名词,其实比较模糊,没有一个广泛认同的严格定义。这里讲一下我个人的理解:

f(i)=⌊ni⌋f(i)=\lfloor \frac{n}{i} \rfloorf(i)=in

f(i)f(i)f(i)的值,随着iii的增加而单调不增,如果我把f(1),f(2),…,f(n)f(1),f(2),\dots,f(n)f(1),f(2),,f(n)从左到右排开,会发现其值呈现出“块状”,每一个“块”就是连续的一段,每个“块”中f(i)f(i)f(i)的值都是相同的

举个例子,n=5n=5n=5

f(1)=5,f(2)=2,f(3)=f(4)=f(5)=1f(1)=5,f(2)=2,f(3)=f(4)=f(5)=1f(1)=5,f(2)=2,f(3)=f(4)=f(5)=1,一字排开,得到5,2,1,1,15,2,1,1,15,2,1,1,1,相同的分到一个“块”中,直观一点,写成:[5],[2],[1,1,1][5],[2],[1,1,1][5],[2],[1,1,1]

数论分块从直观上来讲就是这个现象

数论分块中,块的右端是个很重要的位置。比如例子n=5n=5n=5中,三个块右端的编号分别是1,2,51,2,51,2,5

结论一:假设某个块的fff值为ttt,那么这个块右端的下标是⌊nt⌋\lfloor \frac{n}{t} \rfloortn

如果一个块的fff值是ttt,对于其中的数xxx,应当满足⌊nx⌋=t\lfloor \frac{n}{x} \rfloor=txn=t,即n=tx+r(0≤r<x)n=tx+r(0\le r <x)n=tx+r(0r<x),从这个式子中就可以看出xxx的取值是连续的一段整数。块的右端就是满足上式的最大xxx,也就是说xt≤nxt \le nxtn的最大xxx,那么显然xmax=⌊nt⌋x_{max} = \lfloor \frac{n}{t} \rfloorxmax=tn

结论二:f(i)的值域和块右端下标集合是相同的

比如上面那个例子,值域是{1,2,5}\{1,2,5\}{1,2,5},块右端下标集合也是{1,2,5}\{1,2,5\}{1,2,5}

解释:

假设一个块的fff值是ttt,右端是xxx,那么⌊nt⌋=x,⌊nx⌋=t\lfloor \frac{n}{t} \rfloor=x, \lfloor \frac{n}{x} \rfloor=ttn=x,xn=t

也就是说xxxttt一一对应,不同块的fff值不会相同,一个fff值也不会对应多个块,这就说明了块“右端“集合和fff的值域值域这两个集合大小相同

那么元素是否也是相同的呢?是的,因为假设一个元素ppp属于"块右端"集合,那么根据“块右端”的计算方法,得知某个肯定存在某个ttt使得⌊nt⌋=p\lfloor \frac{n}{t} \rfloor=ptn=p,也就是f(t)=pf(t)=pf(t)=p,也就是说ppp也属于fff的值域值域集合。

因为两个集合大小相同,而且“块右端”集合中的每个元素也在值域集合中出现,所以这两个集合相等

结论三:当x≤⌊n⌋x \le \lfloor \sqrt n \rfloorxn时,f(x)f(x)f(x)的值严格单调增

上面提到过一个式子:

n=tx+r(0≤r<x) n=tx+r(0\le r <x) n=tx+r(0r<x)

x<⌊n⌋x< \lfloor \sqrt n \rfloorx<n的时候,如果我在上式中用x+1x+1x+1替换xxx,假设ttt可以保持不变,那么就有

n=t(x+1)+r′(0≤r′<x+1) n = t(x+1) +r' (0 \le r' < x+1) n=t(x+1)+r(0r<x+1)

也就是n=tx+(t+r′)n = tx + (t +r')n=tx+(t+r),那么t+r′=rt+r'=rt+r=r

但是由于x<⌊n⌋x< \lfloor \sqrt n \rfloorx<n,所以t=⌊nx⌋>⌊n⌋>xt =\lfloor \frac{n}{x} \rfloor > \lfloor \sqrt n \rfloor > xt=xn>n>x

那么显然t+r′>xt+r' > xt+r>x

也就是与我一开始的假设相矛盾了

从而也就证明了结论三

小技巧

在杜教筛中,我们要存储S(⌊ni⌋)S(\lfloor \frac{n}{i} \rfloor)S(in)的所有可能值

如果单纯考虑空间最优,我们应该只需要开O(n)O(\sqrt n)O(n)规模的空间

但是算法还受到时间限制,最后通过均值不等式我们发现最好是预处理到O(n23)O(n^{\frac{2}{3}})O(n32)可以得到一个最优的时间复杂度。当然实际中还是要调参,因为各个部分的时间占比并非相同。

回归正题,在min25min25min25筛和杜教筛中我们都要解决一个问题:存储一些数据,这些数据的下标很大,但是这些下标都在⌊ni⌋\lfloor \frac{n}{i} \rfloorin的值域中。根据本文所介绍的理论,当i≤⌊n⌋i\le \lfloor \sqrt n \rfloorin的时候直接块右端(根据结论三,块右端就是1,2,…,⌊n⌋1,2,\dots,\lfloor \sqrt n \rfloor1,2,,n)为下标,而当i>⌊n⌋i > \lfloor \sqrt n \rfloori>n的时候以值为下标。

大的部分想调用的时候,直接计算一下块右端下标就可以访问了。

这样调用是O(1)O(1)O(1)的,显然比用map或者unorderd_map快得多

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值