整除+数论分块

参考: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\)

练习

https://www.luogu.com.cn/problem/P2260

posted @ 2024-08-10 11:29  hhhqx  阅读(6)  评论(0)    收藏  举报