浅谈整除分块
整除分块是一个挺简单但是应用极广的算法。
听上去挺难,实际不难。
实则它是解决这样一类问题:
求:
n∑i=1⌊ni⌋
你可能觉得这个式子无法下手,连个 gcd 也推不起来。
我们下面证明一个结论:
在 \lfloor \frac{n}{1} \rfloor,\lfloor \frac{n}{2} \rfloor \cdots \lfloor \frac{n}{n} \rfloor 中,
不同的数值 最多 有 2 \times \sqrt{n} 个。
证:
首先, i \leq \sqrt{n} 的时候,肯定取值不超过 \sqrt{n} 个。
其次,i > \sqrt{n} 的时候,会有:
\lfloor \frac{n}{i} \rfloor < \sqrt{n}
这个性质不明白,可以去重学因数了
所以,不同的取值也不超过 \sqrt{n} 个。(实际不能等于 \sqrt{n},但是我们不在乎这点常数)
所以,总取值不超过 2 \times \sqrt{n} 个。
这是数学上的说法,在编程上说,我们忽略常数,就说是 \sqrt{n} 个(指时间级别)。
所以,本题可以迅速解决。
for(ll i=1,t;i<=n;i=t+1) { //i是块的开头,t是块的末尾,每次枚举一个块
t=n/(n/i); ll len=(t-i+1)%MOD; //算出块的长度和末尾
ans=(ans+len*(n/i)%MOD)%MOD; //统计
}
(这是伪代码,大家欣赏下就行)
整除分块是常用技巧,一定要学会哦!
简易的代码胜过复杂的说教。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步