博客
关于我
P2260 [清华集训2012]模积和
阅读量:798 次
发布时间:2023-02-26

本文共 1450 字,大约阅读时间需要 4 分钟。

要解决这个问题,我们需要计算双重求和:$\sum\limits_{i=1}^{n} \sum\limits_{j=1}^{m} (n \bmod i) \times (m \bmod j)$,其中条件是$i \neq j$,然后对结果取模19940417。

方法思路

  • 忽略条件:首先计算不考虑$i \neq j$条件下的总和。
  • 分解求和:将双重求和分解为两个单独的求和,然后相乘。
  • 处理条件:减去$i = j$的情况。
  • 高效计算:使用分块求和方法来处理大数,避免逐项计算。
  • 解决代码

    #include 
    using namespace std;const int mod = 19940417;ll solve(ll x) { ll ans = 0; ll p, i; for (i = 1, p = x; i <= p; i++) { p = x / i; if (i > p) break; ans = (ans - (p + i) * (p - i + 1) / 2 % mod) % mod; } return ans;}ll get(ll x) { return x * (x + 1) % mod; x = x % mod; x = x * (2 * x + 1) % mod; return x * inv % mod;}int main() { ios::sync_with_stdio(0); cin >> n >> m; ll sum_n = solve(n); ll sum_m = solve(m); ll total = (sum_n * sum_m) % mod; if (n > m) swap(n, m); for (ll i = 1; i <= n; i++) { ll p = min(n / i, m / i); if (i > p) continue; ll term1 = (m * n % mod) * (p - i + 1) % mod; ll term2 = (n / i) * (m / i) % mod; term2 = term2 * (get(p) - get(i - 1)) % mod; ll term3 = (p - i + 1) * (p + i) / 2 % mod; term3 = term3 * (n / i) % mod; term3 = term3 * (m % mod) % mod; term3 = term3 * (n % mod) % mod; total = (total - (term1 + term2 - term3) % mod) % mod; } cout << total % mod << endl;}

    代码解释

  • solve函数:计算$\sum_{i=1}^{x} (x \bmod i)$,使用分块求和方法。
  • get函数:计算平方和的模运算形式,使用逆元处理。
  • 主函数:读取输入,计算总和,并处理$i = j$的情况,最后输出结果。
  • 这个方法高效地处理了大数范围,确保了计算的可行性和效率。

    转载地址:http://mdvfk.baihongyu.com/

    你可能感兴趣的文章