【2019银联高校极客挑战赛 初赛 第二场】B. 码队弟弟的求和问题
题意:
计算:
\[\begin{eqnarray*}
\sum\limits_{i = 1}^n \sum\limits_{j = 1}^m (ij(n \bmod i)(m \bmod j)) \bmod (10^9 + 7)
\end{eqnarray*}
\]
思路:
考虑\(x \bmod y = x - \left\lfloor \frac{x}{y} \right\rfloor \cdot y\),那么将式子化简,有:
\[\begin{eqnarray*}
&&\sum\limits_{i = 1}^n \sum\limits_{j = 1}^m (ij(n - \left\lfloor \frac{n}{i} \right\rfloor \cdot i) (m - \left\lfloor \frac{m}{j} \right\rfloor \cdot j)) \bmod (10^9 + 7) \\
&=& \sum\limits_{i = 1}^n (i \cdot (n - \left\lfloor \frac{n}{i} \right\rfloor \cdot i)) \sum\limits_{j = 1}^m (j \cdot (m - \left\lfloor \frac{m}{j} \right\rfloor \cdot j)) \bmod (10^9 + 7)
\end{eqnarray*}
\]
然后分块计算即可。
代码:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll p = 1e9 + 7;
ll n, m, inv6;
ll qmod(ll base, ll n) {
ll res = 1;
while (n) {
if (n & 1) res = res * base % p;
base = base * base % p;
n >>= 1;
}
return res;
}
ll f(ll x) {
return (x * (x + 1) / 2) % p;
}
ll f2(ll x) {
return x * (x + 1) % p * (2 * x + 1) % p * inv6 % p;
}
ll g(ll l, ll r) {
return (f2(r) - f2(l - 1) + p) % p;
}
int main() {
inv6 = qmod(6, p - 2);
while (scanf("%lld%lld", &n, &m) != EOF) {
ll tot = m * f(m) % p;
for (int i = 1, j; i <= m; i = j + 1) {
j = m / (m / i);
tot -= 1ll * g(i, j) * (m / i) % p;
tot = (tot + p) % p;
}
ll res = n * f(n) % p * tot % p;
for (int i = 1, j; i <= n; i = j + 1) {
j = n / (n / i);
res -= 1ll * g(i, j) * (n / i) % p * tot % p;
res = (res + p) % p;
}
printf("%lld\n", res);
}
return 0;
}

浙公网安备 33010602011771号