[国家集训队]Crash的数字表格 / JZPTAB 题解

知识点:

Dirichlet 前缀和 + 线性筛。

推导:

默认 (n leq m)

(ans = displaystyle sum_{i = 1}^n sum_{j = 1}^{m} lcm(i,j) \ = displaystyle sum_{d = 1}^{n} d sum_{i = 1}^{lfloor frac{n}{d} floor} sum_{j = 1}^{lfloor frac{m}{d} floor} ij \ = displaystyle sum_{d = 1}^{n} d sum_{i = 1}^{lfloor frac{n}{d} floor} sum_{j = 1}^{lfloor frac{m}{d} floor} ij \ = displaystyle sum_{d = 1}^{n} d sum_{k = 1}^{lfloor frac{n}{d} floor} mu(k)k^2 sum_{i = 1}^{lfloor frac{n}{kd} floor} sum_{j = 1}^{lfloor frac{m}{kd} floor} ij)

下面不妨令 (T = kd)。可以得到:

(ans = displaystyle sum_{T = 1}^n T sum_{d|T} mu(d)d sum_{i = 1}^{lfloor frac{n}{T} floor} sum_{j = 1}^{lfloor frac{m}{T} floor} ij)

不妨令 (g(n, T)) = (displaystyle sum_{i = 1}^{lfloor frac{n}{T} floor}),可以很容易得到 (g(T) = (frac{n}{T} + 1) * frac{n}{T} / 2)

那么

(ans = displaystyle sum_{T = 1}^n (T sum_{d|T} mu(d)d) imes g(n, T) imes g(m, T))

前面的 (displaystyle sum_{d|T} mu(d)d) 用 Dirichlet 前缀和预处理即可在 (O(n log log n)) 的复杂度内完成问题的预处理。

对于询问用整除分块优化即可做到 (sqrt{n}) 处理。

Code

#include <bits/stdc++.h>
using namespace std;
const int Mod = 20101009, MAXN = 1e7 + 5, inv = (Mod + 1) >> 1;
int n, m;
int Prime[MAXN / 11], Mu[MAXN], tot = 0, S[MAXN];
bool bk[MAXN];
void GetPrime(int N) {
    Mu[1] = 1;
    for(int i = 2 ; i <= N ; i ++) {
        if(!bk[i]) Prime[++ tot] = i, Mu[i] = -1; 
        for(int j = 1 ; j <= tot && Prime[j] * i <= N; j ++) {
            bk[Prime[j] * i] = 1;
            if(i % Prime[j] == 0) break;
            Mu[Prime[j] * i] = - Mu[i];
        }
    }
    for(int i = 1 ; i <= N ; i ++) S[i] = 1ll * ((Mu[i] + Mod) % Mod) * i % Mod;
    return ;
}
int Sum(int x) { return 1ll * x * (x + 1) % Mod * inv % Mod; }

int main() {
    cin >> n >> m;
    if(n > m) swap(n, m);
    GetPrime(n);
    for(int i = 1 ; i <= tot ; i ++) 
        for(int j = 1 ; j * Prime[i] <= n ; j ++)
        S[Prime[i] * j] += S[j], S[Prime[i] * j] %= Mod;
    int Ans = 0;
    for(int i = 1 ; i <= n ; i ++) {
        Ans += 1ll * i * S[i] % Mod * Sum(n / i) % Mod * Sum(m / i) % Mod;
        Ans %= Mod;
    }
    cout << Ans;
    return 0;
}
By MYCui
原文地址:https://www.cnblogs.com/MYCui/p/15028784.html