整除+数论分块
参考:https://oi-wiki.org/math/number-theory/sqrt-decomposition/
整除分块就是引理2搞出来的一种东西。模板题就是根号复杂度求出 \(\sum\limits_{i=1}^{n}{\left\lfloor \frac{n}{i} \right\rfloor}\)。
另外,由于整除分块好推且有些细节,建议场上自己推一遍。
引理 1
\(\forall a,b,c \in \mathbb{Z}, \left\lfloor\dfrac{a}{bc}\right\rfloor = \left\lfloor\dfrac{\left\lfloor\frac{a}{b}\right\rfloor}{c}\right\rfloor\)
证明:
- 有 \(\frac{a}{b} = \left\lfloor\frac{a}{b}\right\rfloor+r(0 \le r < 1)\)
- 则 \(\left\lfloor\dfrac{a}{bc}\right\rfloor = \left\lfloor\dfrac{\frac{a}{b}}{c}\right\rfloor = \left\lfloor\dfrac{\left\lfloor\frac{a}{b}\right\rfloor}{c} + \dfrac{r}{c}\right\rfloor = \left\lfloor\dfrac{\left\lfloor\frac{a}{b}\right\rfloor}{c}\right\rfloor\)
- (最后一步变换可以分类讨论证明)
引理 2
\(\forall n \in \mathbb{N}_{+}\),\(\left\lfloor\dfrac{n}{d}\right\rfloor\) 最多只有 \(\left\lfloor2\sqrt{n}\right\rfloor\) 种。
证明:
- 对于 \(d \le \left\lfloor\sqrt{n}\right\rfloor\) 最多 \(\left\lfloor\sqrt{n}\right\rfloor\) 种
- 对于 \(d > \left\lfloor\sqrt{n}\right\rfloor\) 有 \(\left\lfloor\frac{n}{d}\right\rfloor \le \left\lfloor\sqrt{n}\right\rfloor\),最多 \(\left\lfloor\sqrt{n}\right\rfloor\) 种
引理 3
\(\left\lceil\dfrac{n}{x}\right\rceil = \left\lfloor\dfrac{n-1}{x}\right\rfloor + 1\)
\(\left\lceil\dfrac{n}{x}\right\rceil - 1 = \left\lfloor\dfrac{n-1}{x}\right\rfloor\)
\(\left\lceil\dfrac{n+1}{x}\right\rceil = \left\lfloor\dfrac{n}{x}\right\rfloor + 1\)
\(\left\lceil\dfrac{n+1}{x}\right\rceil - 1 = \left\lfloor\dfrac{n}{x}\right\rfloor\)
引理 4
根据引理 3 的 \(\left\lceil\dfrac{n}{x}\right\rceil = \left\lfloor\dfrac{n-1}{x}\right\rfloor + 1\),能推出: \(\left\lceil \dfrac{\left\lceil \frac{a}{b}\right\rceil}{c}\right\rceil = \left\lfloor \frac{a-1}{bc}\right\rfloor + 1\)。
整除分块
设块的右端点 \(l\),则需要找到最大 \(r\) 满足 \(\left\lfloor\dfrac{n}{l}\right\rfloor \le \dfrac{n}{r} < \left\lfloor\dfrac{n}{l}\right\rfloor + 1\)
左边的不等式解得:\(r \le \left\lfloor\dfrac{n}{\left\lfloor\dfrac{n}{l}\right\rfloor}\right\rfloor\),若以 \(r\) 的最大值也是这个。
模板题:https://www.luogu.com.cn/problem/UVA11526
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
int T;
LL n;
int main(){
ios::sync_with_stdio(0), cin.tie(0);
cin >> T;
while(T--){
cin >> n;
LL ans = 0;
for(LL l = 1, r; l <= n; l = r + 1){
r = n / (n / l);
ans += (r - l + 1) * (n / l);
}
cout << ans << "\n";
}
return 0;
}
关于两个数同时整除分块:https://www.luogu.com.cn/problem/P3327
可以直接两个的右端点取 \(\min\)
向上取整
设块左端点 \(l\),则需要找到最大的 \(r\) 满足 \(\left\lceil\dfrac{n}{l}\right\rceil - 1 < \dfrac{n}{r} \le \left\lceil\dfrac{n}{l}\right\rceil\),推式子(显然只用推左侧的不等式),先要熟悉引理 3,会快很多:
- \(\left\lfloor\dfrac{n-1}{l}\right\rfloor < \dfrac{n}{r}\)
- \(r < \dfrac{n}{\left\lfloor\dfrac{n-1}{l}\right\rfloor}\)
- \(r < \left\lceil \dfrac{n}{\left\lfloor\dfrac{n-1}{l}\right\rfloor} \right\rceil\)(这一步可以分类讨论证明)
- \(r < \left\lfloor \dfrac{n - 1}{\left\lfloor\dfrac{n-1}{l}\right\rfloor} \right\rfloor + 1\)
- \(r \le \left\lfloor \dfrac{n - 1}{\left\lfloor\dfrac{n-1}{l}\right\rfloor} \right\rfloor\)

浙公网安备 33010602011771号