浅谈整除分块

博客园同步

整除分块是一个挺简单但是应用极广的算法。

听上去挺难,实际不难。

实则它是解决这样一类问题:

求:

∑ i = 1 n ⌊ n i ⌋ \sum_{i=1}^n \lfloor \frac{n}{i} \rfloor i=1nin

你可能觉得这个式子无法下手,连个 gcd ⁡ \gcd gcd 也推不起来。

我们下面证明一个结论:

⌊ n 1 ⌋ \lfloor \frac{n}{1} \rfloor 1n ⌊ n 2 ⌋ ⋯ ⌊ n n ⌋ \lfloor \frac{n}{2} \rfloor \cdots \lfloor \frac{n}{n} \rfloor 2nnn 中,

不同的数值 最多 2 × n 2 \times \sqrt{n} 2×n 个。

证:

首先, i ≤ n i \leq \sqrt{n} in 的时候,肯定取值不超过 n \sqrt{n} n 个。

其次, i > n i > \sqrt{n} i>n 的时候,会有:

⌊ n i ⌋ < n \lfloor \frac{n}{i} \rfloor < \sqrt{n} in<n

这个性质不明白,可以去重学因数了

所以,不同的取值也不超过 n \sqrt{n} n 个。(实际不能等于 n \sqrt{n} n ,但是我们不在乎这点常数)

所以,总取值不超过 2 × n 2 \times \sqrt{n} 2×n 个。

这是数学上的说法,在编程上说,我们忽略常数,就说是 n \sqrt{n} 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; //统计
} 

(这是伪代码,大家欣赏下就行)

整除分块是常用技巧,一定要学会哦!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值