[清华集训2012]模积和
Description
求
\[\sum_{i=1}^{n}\sum_{j=1}^{m} (n\bmod i)(m\bmod j)[i \ne j]
\]
Solution
看到取模就会想整除分块的吧,那个\([i\ne j]\)其实也很好处理啊,就是最后再减去\(i=j\)的情况就行了。
我式子推的有点丑……
\[\sum_{i=1}^{n}\sum_{j=1}^{m} (n\bmod i)(m\bmod j)[i \ne j]\\
= \sum_{i=1}^{n}\sum_{j=1}^{m} (n\bmod i)(m\bmod j) - \sum_{i=1}^{\min(n, m)} (n\bmod i)(m\bmod i)\\
= \sum_{i=1}^{n}\sum_{j=1}^{m} (n - \lfloor\dfrac{n}{i}\rfloor i)(m - \lfloor\dfrac{m}{j}\rfloor j) - \sum_{i=1}^{\min(n, m)} (n - \lfloor\dfrac{n}{i}\rfloor i)(m - \lfloor\dfrac{m}{i}\rfloor i)\\
= \sum_{i=1}^{n}\sum_{j=1}^{m} (nm - m\lfloor\dfrac{n}{i}\rfloor i - n\lfloor\dfrac{m}{j}\rfloor j + \lfloor\dfrac{n}{i}\rfloor i\lfloor\dfrac{m}{j}\rfloor j) - \sum_{i=1}^{\min(n, m)}\mbox{...}\\
= n^2m^2 - m^2\sum_{i=1}^{n}\lfloor\dfrac{n}{i}\rfloor i - \mbox{...}
\]
后面就是一些sb的去括号了,没啥好说的了。
Code
#include <cstdio>
#include <algorithm>
typedef long long LL;
const LL MOD = 19940417;
const LL I2 = 9970209;
const LL I6 = 3323403;
int n, m;
LL sp(LL x) {
return x * (2 * x + 1) % MOD * (x + 1) % MOD * I6 % MOD;
}
int main() {
scanf("%d%d", &n, &m);
if (n < m) std::swap(n, m);
LL ans = n % MOD * n % MOD * m % MOD * m % MOD;
LL si = 0, sj = 0, sij = 0;
for (int i = 1, j; i <= n; i = j+1) {
j = n / (n / i);
si = (si + (n / i) * (i + j) % MOD * (j - i + 1) % MOD * I2 % MOD) % MOD;
}
for (int i = 1, j; i <= m; i = j+1) {
j = m / (m / i);
sj = (sj + (m / i) * (i + j) % MOD * (j - i + 1) % MOD * I2 % MOD) % MOD;
}
ans = ((ans - m % MOD * m % MOD * si % MOD - n % MOD * n % MOD * sj % MOD) %MOD + MOD) % MOD;
sij = si * sj % MOD;
ans = (ans + sij) % MOD;
ans = (ans - m % MOD * m % MOD * n % MOD + MOD) % MOD;
si = 0;
for (int i = 1, j; i <= m; i = j+1) {
j = std::min(m, n / (n / i));
si = (si + (n / i) * (i + j) % MOD * (j - i + 1) % MOD * I2 % MOD) % MOD;
}
ans = (ans + m % MOD * si % MOD + n % MOD * sj % MOD) % MOD;
sj = 0;
for (int i = 1, j; i <= m; i = j+1) {
j = std::min(n / (n / i) , m / (m / i));
sj = (sj + (n / i) % MOD * (m / i) % MOD * (sp(j) - sp(i-1) + MOD) % MOD) % MOD;
}
ans = (ans - sj + MOD) % MOD;
printf("%d\n", ans);
return 0;
}