模积和
题意:求出
$ \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)\)