模積和
題意:求出
$ \sum_{i=1}^n \sum_{j=1}^m(n \bmod i)\times(m\bmod j) $ 且 $ i\ne j $ 。
思路
10ps
\(O(nm)\) 暴力
30ps
首先我們發現可以將原式拆解一下,就可以變成
但是這樣是不對的,因為我們沒有考慮 \(i=j\) 的情況,所以正確的式子為
\(O(n+m)\) 的做法就完成了,30分到手。
60ps
根據打表發現,如果套上整除分塊,商為同一個數的所有 \(i\) 會構成一個等差數列。
(以下預設要會整除分塊,不會的先去學)
設當前的商的第一個 \(i\) 為 \(l\) ,最後一個為 \(r\) ,則首項為 \(n\bmod l\) ,公差為 \(-\lfloor \frac{n}{l}\rfloor\) ,項數為 \(r-l+1\) 。
套一個等差數列求和公式,就可以將複雜度降至 \(O(\sqrt n+\sqrt m+n)\)
100ps
現在演算法複雜度的瓶頸全在求 \(\sum_{i-1}^{min(n,m)}(n\bmod i)\times(m\bmod i)\) 上,那麼我們可以嘗試套上整除分塊,那麼還是一樣,設當前的商的第一個 \(i\) 為 \(l\) ,最後一個為 \(r\) ,那麼
設 \(n\) 的首項為 \(ns\) ,\(m\) 的首項為 \(ms\) , \(n\) 的公差為 \(ng\) ,\(m\) 的公差為 \(mg\) ,項數為 \(lg\)。
那麼
我們知道,在這裡面,數列即為
拆解一下,即為
如果我們先不管那些 \(ng·mg\),那麼原式就會變為
我們可以發現,這又是一個等差數列,首項為 \(ns·ms\) ,項數為 \(lg\) ,公差為 \(-ng·ms-ns·mg\) ,於是這一部分就完成了。
現在我們看到 \(ng·mg\),發現他們的係數分別為
那麼這一部分就需要用到平方和公式了,即
那麼這一部分就完成了。
最後將這兩部分加起來,然後用一開始的容減去這個斥就可以得到答案。
複雜度 \(O(\sqrt n+\sqrt m)\)