知识点 - 整除分块

知识点 - 整除分块

1.约数个数

τ ( n ) \tau(n) τ(n)为n的约数个数,求其前缀和。

解析

若n的质因数分解为 n = p 1 e 1 ⋅ p 2 e 2 ⋯ p k e k n=p_1^{e_1} \cdot p_2^{e_2} \cdots p_k^{e_k} n=p1e1p2e2pkek,则
τ ( n ) = ( e 1 + 1 ) ⋅ ( e 2 + 1 ) ⋯ ( e k + 1 ) \tau(n) = (e_1 + 1) \cdot (e_2 + 1) \cdots (e_k + 1) τ(n)=(e1+1)(e2+1)(ek+1)
不过求这个前缀和时不需要此公式。

我们有
∑ i = 1 n τ ( i ) = ∑ i = 1 n ∑ j = 1 n [ j ∣ i ] = ∑ i = 1 n ⌊ n i ⌋ \sum_{i=1}^{n}\tau(i)=\sum_{i=1}^{n}{\sum_{j=1}^{n}{[j|i]}}=\sum_{i=1}^{n}\lfloor\frac {n}{i}\rfloor i=1nτ(i)=i=1nj=1n[ji]=i=1nin
对于
y 1 = ⌊ n x ⌋   y 2 = n x y_1=\lfloor\frac{n}{x}\rfloor\\\ \\ y_2=\frac{n}{x} y1=xn y2=xn
n = 12 n=12 n=12时作图如下:
在这里插入图片描述

i ≤ n i≤\sqrt n in 时, ⌊ n i ⌋ \lfloor\frac{n}{i}\rfloor in显然只有 O ( n ) O(\sqrt n) O(n )个取值;当 i &gt; n i&gt;\sqrt n i>n 时, ⌊ n i ⌋ &lt; n \lfloor\frac{n}{i}\rfloor&lt;\sqrt n in<n 显然也只有 O ( n ) O(\sqrt n) O(n )个取值;
对于固定 ⌊ n i ⌋ \lfloor\frac{n}{i}\rfloor in, i i i的取值是一段连续的区间,这段区间是 [ ⌊ n ⌊ n i ⌋ + 1 ⌋ + 1 , ⌊ n ⌊ n i ⌋ ⌋ ] [\left\lfloor\frac{n}{\left\lfloor\frac{n}{i}\right\rfloor+1}\right\rfloor+1,\left\lfloor\frac{n}{\left\lfloor\frac{n}{i}\right\rfloor}\right\rfloor] [in+1n+1,inn]
几何上可以理解为先找到对应的红线,即求出i点的值 v = ⌊ n i ⌋ v=\lfloor\frac{n}{i}\rfloor v=in;然后求出红线的终点,即右区间 r = ⌊ n v ⌋ r=\lfloor\frac{n}{v}\rfloor r=vn,以及它的起点 l = ⌊ n v + 1 ⌋ l=\lfloor\frac{n}{v+1}\rfloor l=v+1n

⌊ n ⌊ n i ⌋ ⌋ \left\lfloor\frac{n}{\left\lfloor\frac{n}{i}\right\rfloor}\right\rfloor inn作为分界线,所以有如下代码:

	int ans = 0;
	for (int l = 1, r; l <= n; l = r + 1){
		r = n / (n / l);
		ans += (r - l + 1)*(n / l);
	}

右区间的代数证明,?戳这里。

2.约数和

σ ( i ) \sigma(i) σ(i)为n的约数和,求前缀和。

oeis A024916

约数和

解析

类似上面,有:
σ ( n ) = p 1 e 1 + 1 − 1 p 1 − 1 ⋅ p 2 e 2 + 1 − 1 p 2 − 1 ⋯ p k e k + 1 − 1 p k − 1 \sigma(n) = \frac{p_1^{e_1 + 1} - 1}{p_1 - 1} \cdot \frac{p_2^{e_2 + 1} - 1}{p_2 - 1} \cdots \frac{p_k^{e_k + 1} - 1}{p_k - 1} σ(n)=p11p1e1+11p21p2e2+11pk1pkek+11
同上也没用。因为我们可以直接写出:
∑ i = 1 n σ ( i ) = ∑ i = 1 n ∑ j = 1 n [ j ∣ i ] ⋅ j = ∑ i = 1 n i ⋅ ∑ j = 1 n [ i ∣ j ] = ∑ i = 1 n i ⋅ ⌊ n i ⌋ = ∑ i = 1 n ⌊ n i ⌋ ⋅ ( ⌊ n i ⌋ + 1 ) 2 \sum_{i=1}^{n}{\sigma(i)}=\sum_{i=1}^{n}{\sum_{j=1}^{n}{[j|i]\cdot j}}=\sum_{i=1}^{n}{i\cdot\sum_{j=1}^{n}{[i|j]}}=\sum_{i=1}^{n}{i\cdot\lfloor\frac{n}{i}\rfloor}=\sum_{i=1}^{n}{\frac{\lfloor\frac{n}{i}\rfloor\cdot (\lfloor\frac{n}{i}\rfloor+1)}{2}} i=1nσ(i)=i=1nj=1n[ji]j=i=1nij=1n[ij]=i=1niin=i=1n2in(in+1)
最后的等式
∑ i = 1 n i ⋅ ⌊ n i ⌋ = ∑ i = 1 n ⌊ n i ⌋ ⋅ ( ⌊ n i ⌋ + 1 ) 2 \sum_{i=1}^{n}{i\cdot\lfloor\frac{n}{i}\rfloor}=\sum_{i=1}^{n}{\frac{\lfloor\frac{n}{i}\rfloor\cdot (\lfloor\frac{n}{i}\rfloor+1)}{2}} i=1niin=i=1n2in(in+1)
可以看成对每个 ⌊ n i ⌋ \lfloor\frac{n}{i}\rfloor in固定的块,将 ⌊ n i ⌋ \lfloor\frac{n}{i}\rfloor in提出来,然后对 i ∈ [ ⌊ n ⌊ n i ⌋ + 1 ⌋ + 1 , ⌊ n ⌊ n i ⌋ ⌋ ] i\in[\left\lfloor\frac{n}{\left\lfloor\frac{n}{i}\right\rfloor+1}\right\rfloor+1,\left\lfloor\frac{n}{\left\lfloor\frac{n}{i}\right\rfloor}\right\rfloor] i[in+1n+1,inn]等差数列求和。

int f(int n) {
	int ans = 0;
	for (int l = 1, r; l <= n; l = r + 1) {
		r = n / (n / l);
		ans += (r - l + 1)*(n / l)*(n / l + 1) / 2;
	}
	return ans;
}
signed main()
{
	int l, r;
	while (cin >> l>>r) {
		cout << f(r) - f(l - 1) << endl;
	}
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Best KeyBoard

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值