整除分块

整除分块

例题:

已知 \(f(n) =\sum\limits_{i = 1 }^{n}\left\lfloor\frac{n}{i}\right\rfloor\),给定 \(n\),求 \(f(n)\) 的值。

固然可以 \(O(n)\) 暴力,但显然会\(TLE\)

计算一下前几项的值之后可以发现\(\left \lfloor \frac{n}{i} \right \rfloor\) 的取值在连续的一段区间内是相同的,那么就可以将其分为若干块分别进行计算。

先让 \(l\) 为区间的左端点,那么这块的值都为 \(k = \left\lfloor\frac{n}{l}\right\rfloor\)\(r=max(i)=\left\lfloor\frac{n}{k}\right\rfloor\)。将 \(k\) 代入,得到 \(r=\left\lfloor\frac{n}{\left\lfloor\frac{n}{l}\right\rfloor}\right\rfloor\)。这样每一块的左右端点都能用确定的式子得到了。这样分块的值就为单值 $\times $ 区间长度,即 \(k\times (r-l+1)\)

 

模板:

代码
ll division_block(ll n){
	ll res = 0;
    for(ll l = 1, r; l <= n; l = r + 1){
        r = n / (n / l);
        res += n / l * (r - l + 1);
    }
    return res;
}

 

posted @ 2024-06-29 19:48  programmingysx  阅读(2)  评论(0编辑  收藏  举报