整除分塊

programmingysx發表於2024-06-29

整除分塊

例題:

已知 \(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;
}

 

相關文章