∑∑((n mod i) * (m mod j)) 1<=i<=n, 1<=j<=m, i≠j
= ∑(n mod i) * ∑(m mod i) - ∑((n mod i) * (m mod i))
= ∑(n-[n/i]*i) * ∑(m-[m/i]*i) - ∑(nm-([n/i]+[m/i])i+[n/i][m/i])
然后就分块暴力了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| #include <cstdio>
#include <algorithm>
const long long MOD = 19940417;
inline long long sumsqr(const long long n) { return n * (n+1) % MOD * (2*n+1) % MOD * 23263820 % MOD; }
long long calc(const long long n, const long long k)
{
long long res = 0;
for (long long i = 1, last; i <= n; i = last+1)
{
last = std::min(n, k/(k/i));
(res += (k/i) * (i+last) % MOD * (last-i+1) % MOD * 29910626 % MOD) %= MOD;
}
return res;
}
long long n, m;
int main()
{
scanf("%lld%lld", &n, &m);
if (n < m) std::swap(n, m);
long long ans = (n*n-calc(n, n)) % MOD * ((m*m-calc(m, m)) % MOD);
(ans += -m * m % MOD * n % MOD + calc(m, n) * m % MOD + calc(m, m) * n % MOD) %= MOD;
for (long long i = 1, last; i <= m; i = last+1)
{
last = std::min(m, std::min(n/(n/i), m/(m/i)));
(ans += -(n/i) * (m/i) % MOD * ((sumsqr(last) - sumsqr(i-1)) % MOD) % MOD) %= MOD;
}
printf("%lld", (ans%MOD+MOD)%MOD);
}
|