参考资料
https://zhuanlan.zhihu.com/p/513784838
https://oi-wiki.org/math/number-theory/sqrt-decomposition/
常见化整除的公式
a m o d b = a − ⌊ a b ⌋ ∗ b ⌈ a b ⌉ = ⌊ a − 1 b ⌋ + 1 a\ mod\ b = a - \lfloor{\frac{a}{b}}\rfloor * b\\ \lceil \frac{a}{b}\rceil = \lfloor \frac{a - 1}{b}\rfloor + 1 a mod b=a−⌊ba⌋∗b⌈ba⌉=⌊ba−1⌋+1
数论分块结论
对常数num,使得式子
⌊ n u m i ⌋ = ⌊ n u m j ⌋ \lfloor\frac{num}{i}\rfloor = \lfloor\frac{num}{j}\rfloor ⌊inum⌋=⌊jnum⌋
成立的最大满足 i < = j < = n i<=j<= n i<=j<=n的 j j j 值为 $ \lfloor \frac{num}{\lfloor{\frac{num}{i}}\rfloor}\rfloor$即 ⌊ n u m i ⌋ \lfloor\frac{num}{i}\rfloor ⌊inum⌋所在块的右端点为
⌊ n u m ⌊ n u m i ⌋ ⌋ \lfloor \frac{num}{\lfloor{\frac{num}{i}}\rfloor}\rfloor ⌊⌊inum⌋num⌋
应用
对形如
∑
i
=
s
t
e
d
f
(
i
)
⌊
n
u
m
i
⌋
\sum_{i = st}^{ed} f(i)\lfloor\frac{num}{i}\rfloor
i=st∑edf(i)⌊inum⌋
的式子,
⌊
n
u
m
i
⌋
\lfloor\frac{num}{i}\rfloor
⌊inum⌋呈块状分布,若能线性求出
∑
f
(
i
)
\sum f(i)
∑f(i),那么复杂可以通过分块降到
O
(
n
)
O(\sqrt n)
O(n)
代码
//计算区间[st,ed]式子值
int f(int l,int r)//若f(i) = i,求[l,r]内f(i)的和
{
return r - l + 1;
}
int block(int st, int ed, int num) {
int R = 0;//块的右边界
int ans = 0;
ed = min(ed, num);//大于num下整除都是0
for (int i = st; i <= ed; i = R + 1) {
R = min(ed,num / (num / i)); //该区间的最后一个数
ans += f(i,R)*(num / i);//区间[i,L]的num/i 都是一个值
}
return ans;
}