数论分块与整除相

引理一

$$forall a,b,cinmathbb{Z},leftlfloorfrac{a}{bc} ight floor=leftlfloorfrac{leftlfloorfrac{a}{b} ight floor}{c} ight floor$$

略证:

egin{split} &frac{a}{b}=leftlfloorfrac{a}{b} ight floor+r(0leq r<1)\ Rightarrow &leftlfloorfrac{a}{bc} ight floor =leftlfloorfrac{a}{b}cdotfrac{1}{c} ight floor =leftlfloor frac{1}{c}left(leftlfloorfrac{a}{b} ight floor+r ight) ight floor =leftlfloor frac{leftlfloorfrac{a}{b} ight floor}{c} +frac{r}{c} ight floor =leftlfloor frac{leftlfloorfrac{a}{b} ight floor}{c} ight floor\ &&square end{split}

引理二

$$forall n in N, left|left{ lfloor frac{n}{d} floor mid d in N ight} ight| leq lfloor 2sqrt{n} floor$$

$|V|$表示集合$V$的元素个数

略证:

对于$d leq left lfloor sqrt{n} ight floor$,$left lfloor frac{n}{d} ight floor$有$left lfloor sqrt{n} ight floor$种取值.

对于$d geq left lfloor sqrt{n} ight floor$,有$left lfloor frac{n}{d} ight floor leq left lfloor sqrt{n} ight floor$,也只有$left lfloor sqrt{n} ight floor$种取值.

数论分块

数论分块的过程大概如下:考虑含有$left lfloor frac{n}{i} ight floor$的求和式子($n$为常数)

对于任意一个$i$($i leq n$),我们需要找到一个最大的$j$($i leq j leq n$),使得$left lfloor frac{n}{i} ight floor = left lfloor frac{n}{i} ight floor$.

那么$j = left lfloor frac{n}{left lfloor frac{n}{i} ight floor} ight floor$.

略证:

egin{split} &leftlfloorfrac{n}{i} ight floor leq frac{n}{i}\ Rightarrow &leftlfloorfrac{n}{ leftlfloorfrac{n}{i} ight floor } ight floor geq leftlfloorfrac{n}{ frac{n}{i} } ight floor = leftlfloor i ight floor=i \ Rightarrow &ileq leftlfloorfrac{n}{ leftlfloorfrac{n}{i} ight floor } ight floor\ &&square end{split}

即$j = left lfloor frac{n}{left lfloor frac{n}{i} ight floor} ight floor$.

利用上述结论,我们每次以$[i,j]$为一块,分块求和即可.

实现

快速计算$sum left lfloor frac{n}{i} ight floor$的方法:

1 for(int l = 1, r; l <= n;l = r+1)
2 {
3     r = n / (n / l);
4     ans += (r-l+1) * (n / l);
5     printf("%d  %d  %d  %d
", l, r, n/l, n/r);
6 }

参考链接:https://oi-wiki.org/math/mobius/

原文地址:https://www.cnblogs.com/lfri/p/11173941.html