[洛谷 P1829] Crash的数字表格 (莫比乌斯反演)

题意:

∑ i = 1 n ∑ j = 1 m lcm ( i , j ) \sum_{i = 1} ^{n} \sum_{j = 1} ^{m} \text{lcm}(i, j) i=1nj=1mlcm(i,j)

20101009 20101009 20101009 取模

分析:

首先 lcm ( i , j ) = i ⋅ j gcd ⁡ ( i , j ) \text{lcm}(i, j) = \dfrac{i \cdot j}{\gcd(i,j)} lcm(i,j)=gcd(i,j)ij 代入:

∑ i = 1 n ∑ j = 1 m i ⋅ j gcd ⁡ ( i , j ) \sum_{i = 1} ^{n} \sum_{j = 1} ^{m} \frac{i \cdot j}{\gcd(i,j)} i=1nj=1mgcd(i,j)ij

枚举 gcd ⁡ ( i , j ) \gcd(i,j) gcd(i,j)

∑ d = 1 min ⁡ ( n , m ) ∑ i = 1 n ∑ j = 1 m i ⋅ j d [ gcd ⁡ ( i , j ) = d ] \sum_{d = 1} ^{\min(n,m)}\sum_{i = 1} ^{n} \sum_{j = 1} ^{m} \frac{i \cdot j}{d}[\gcd(i,j)=d] d=1min(n,m)i=1nj=1mdij[gcd(i,j)=d]

根据 gcd ⁡ \gcd gcd 的性质:

∑ d = 1 min ⁡ ( n , m ) ∑ i = 1 n ∑ j = 1 m i ⋅ j d [ gcd ⁡ ( i d , j d ) = 1 ] \sum_{d = 1} ^{\min(n,m)}\sum_{i = 1} ^{n} \sum_{j = 1} ^{m} \frac{i \cdot j}{d}[\gcd(\frac{i}{d}, \frac{j}{d}) = 1] d=1min(n,m)i=1nj=1mdij[gcd(di,dj)=1]

i ⋅ j d \dfrac{i \cdot j}{d} dij 中 除一个 d d d 乘一个 d d d,来凑形式一致。

∑ d = 1 min ⁡ ( n , m ) d ∑ i = 1 n ∑ j = 1 m i d ⋅ j d [ gcd ⁡ ( i d , j d ) = 1 ] \sum_{d = 1} ^{\min(n,m)}d \sum_{i = 1} ^{n} \sum_{j = 1} ^{m} \frac{i}{d}\cdot \frac{j}{d} [\gcd(\frac{i}{d}, \frac{j}{d}) = 1] d=1min(n,m)di=1nj=1mdidj[gcd(di,dj)=1]

替换 i d , j d \dfrac{i}{d},\dfrac{j}{d} di,dj

∑ d = 1 min ⁡ ( n , m ) d ∑ i = 1 ⌊ n d ⌋ ∑ j = 1 ⌊ m d ⌋ i ⋅ j [ gcd ⁡ ( i , j ) = 1 ] \sum_{d = 1} ^{\min(n,m)}d \sum_{i = 1} ^{ \lfloor \frac{n}{d} \rfloor } \sum_{j = 1} ^{\lfloor \frac{m}{d} \rfloor }i\cdot j [\gcd(i, j) = 1] d=1min(n,m)di=1dnj=1dmij[gcd(i,j)=1]

用单位函数替换

∑ d = 1 min ⁡ ( n , m ) d ∑ i = 1 ⌊ n d ⌋ ∑ j = 1 ⌊ m d ⌋ i ⋅ j ⋅ ε ( gcd ⁡ ( i , j ) = 1 ) \sum_{d = 1} ^{\min(n,m)}d \sum_{i = 1} ^{ \lfloor \frac{n}{d} \rfloor } \sum_{j = 1} ^{\lfloor \frac{m}{d} \rfloor }i\cdot j \cdot \varepsilon (\gcd(i, j) = 1) d=1min(n,m)di=1dnj=1dmijε(gcd(i,j)=1)

莫比乌斯反演

∑ d = 1 min ⁡ ( n , m ) d ∑ i = 1 ⌊ n d ⌋ ∑ j = 1 ⌊ m d ⌋ i ⋅ j ∑ k ∣ gcd ⁡ ( i , j ) μ ( k ) \sum_{d = 1} ^{\min(n,m)}d \sum_{i = 1} ^{ \lfloor \frac{n}{d} \rfloor } \sum_{j = 1} ^{\lfloor \frac{m}{d} \rfloor }i\cdot j \sum_{k \mid \gcd(i,j)} \mu(k) d=1min(n,m)di=1dnj=1dmijkgcd(i,j)μ(k)

交换求和次序

∑ d = 1 min ⁡ ( n , m ) d ∑ k = 1 min ⁡ ( ⌊ n d ⌋ , ⌊ m d ⌋ ) μ ( k ) ∑ i = 1 ⌊ n d k ⌋ i ⋅ k ∑ j = 1 ⌊ m d k ⌋ j ⋅ k \sum_{d = 1} ^{\min(n,m)}d \sum_{k =1} ^{\min(\lfloor \frac{n}{d} \rfloor,\lfloor \frac{m}{d} \rfloor)} \mu(k) \sum_{i = 1} ^{ \lfloor \frac{n}{dk} \rfloor } i \cdot k \sum_{j = 1} ^{\lfloor \frac{m}{dk} \rfloor } j \cdot k d=1min(n,m)dk=1min(dn,dm)μ(k)i=1dknikj=1dkmjk

整理式子

1 4 ∑ d = 1 min ⁡ ( n , m ) d ∑ k = 1 min ⁡ ( ⌊ n d ⌋ , ⌊ m d ⌋ ) k 2 μ ( k ) ( ⌊ n d k ⌋ 2 + ⌊ n d k ⌋ ) ⋅ ( ⌊ m d k ⌋ 2 + ⌊ m d k ⌋ ) \frac{1}{4} \sum_{d = 1} ^{\min(n,m)}d \sum_{k =1} ^{\min(\lfloor \frac{n}{d} \rfloor,\lfloor \frac{m}{d} \rfloor)} k^2 \mu(k) (\lfloor \frac{n}{dk} \rfloor ^2 + \lfloor \frac{n}{dk} \rfloor) \cdot (\lfloor \frac{m}{dk} \rfloor ^2 + \lfloor \frac{m}{dk} \rfloor) 41d=1min(n,m)dk=1min(dn,dm)k2μ(k)(dkn2+dkn)(dkm2+dkm)

时间复杂度 O ( N N ) O(N\sqrt{N}) O(NN )

代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e7 + 5, mod = 20101009;
int n, m, mobius[N], primes[N], cnt, res, sum[N];
bool st[N];
void get_mobius(int n) {
    mobius[1] = 1;
    for (int i = 2; i <= n; i ++) {
        if (!st[i]) {
            primes[cnt ++] = i;
            mobius[i] = -1;
        }
        for (int j = 0; primes[j] * i <= n; j ++) {
            int t = primes[j] * i;
            st[t] = 1;
            if (i % primes[j] == 0) {
                mobius[t] = 0;
                break;
            }
            mobius[t] = -mobius[i];
        }
    }
    for (int i = 1; i <= n; i ++) sum[i] = (sum[i - 1] + i * i * mobius[i] % mod + mod) % mod;
}
signed main() {
    get_mobius(N - 1);
    cin >> n >> m;
    for (int d = 1; d <= min(n, m); d ++) {
        int x = n / d, y = m / d, Sum = 0;
        for (int l = 1, r; l <= min(x, y); l = r + 1) {
            r = min(x / (x / l), y / (y / l));
            int p = ((x / l) * (x / l) + x / l) / 2 % mod, q = ((y / l) * (y / l) + y / l) / 2 % mod;
            Sum += (sum[r] - sum[l - 1]) % mod * p % mod * q % mod;
            Sum = (Sum % mod + mod) % mod;
        }
        res = (res + d * Sum) % mod;
    }
    cout << res << endl;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值