51nod1238. 最小公倍数之和 V3(莫比乌斯反演)

题目链接

https://www.51nod.com/Challenge/Problem.html#!#problemId=1238

题解

本来想做个杜教筛板子题结果用另一种方法过了......

所谓的“另一种方法”用到的技巧还是挺不错的,因此这里简单介绍一下。

首先还是基本的推式子:

\[\begin{aligned}\sum_{i = 1}^n \sum_{j = 1}^n {\rm lcm}(i, j) &= \sum_{i = 1}^n \sum_{j = 1}^n \frac{ij}{{\rm gcd}(i, j)} \\ &= \sum_{d = 1}^{n} \sum_{i = 1}^n \sum_{j = 1}^n[{\rm gcd}(i, j) = d]\frac{ij}{d} \\ &= \sum_{d = 1}^n d\sum_{i = 1}^{\left\lfloor\frac{n}{d}\right\rfloor}\sum_{j = 1}^{\left\lfloor\frac{n}{d}\right\rfloor}[{\rm gcd}(i, j) = 1]ij\end{aligned}\]

设 \(f(x) = \sum_\limits{i = 1}^x \sum_\limits{j = 1}^x [{\rm gcd}(i, j) = 1]ij\),那么答案即为 \(\sum_\limits{d = 1}^n d\times f(\left\lfloor\frac{n}{d}\right\rfloor)\)。显然答案可以数论分块求,因此我们的任务就是求 \(f\) 函数。

首先考虑当 \(x\) 较小时,我们能否直接预处理出 \(f(x)\)。考虑差分:当 \(x > 1\) 时,\(f(x)\) 较 \(f(x - 1)\) 而言,多了的部分为:\[\left(\sum_\limits{i = 1}^x\sum_\limits{j = 1}^x [{\rm gcd}(i, j) = 1]ij\right) - \left(\sum_\limits{i = 1}^{x - 1}\sum_\limits{j = 1}^{x - 1} [{\rm gcd}(i, j) = 1]ij\right) = 2x \sum_{i = 1}^x [{\rm gcd}(i, x) = 1]i\]

而由于小于等于 \(x(x > 1)\) 且与 \(x\) 互质的数的和为 \(\frac{\varphi(x)x}{2}\)(证明提示:当 \(n \geq 2\) 时,若 \({\rm gcd}(d, n) = 1\) 必然有 \({\rm gcd}(n - d, n) = 1\),与 \(n\) 互质的 \(d\) 共有 \(\varphi(n)\) 个),因此我们就得到了 \(f(x)\) 的递推式:\(f(x) = f(x - 1) + 2x \times \frac{\varphi(x)x}{2}\),即 \(f(x) = f(x - 1) + \varphi(x)x^2\)。

不过这只能处理 \(x\) 较小的情况。当 \(x\) 较大时,我们仍然得另谋他路。在 \(f(x) = \sum_\limits{i = 1}^x \sum_\limits{j = 1}^x [{\rm gcd}(i, j) = 1]ij\) 当中,对 \(f(x)\) 有贡献的 \(i, j\) 满足 \(i\) 与 \(j\) 是互质的,我们考虑补集转化,用总和减去不互质的 \(i, j\) 的贡献:

\[\begin{aligned} f(x) &= \sum_{i = 1}^x\sum_{j = 1}^x ij - \sum_{d = 2}^x \sum_{i = 1}^x \sum_{j = 1}^x [{\rm gcd}(i, j) = d]ij \\ &= \left(\frac{x(x+1)}{2}\right)^2 - \sum_{d = 2}^x d^2 \sum_{i = 1}^{\left\lfloor\frac{x}{d}\right\rfloor} \sum_{j = 1}^{\left\lfloor\frac{x}{d}\right\rfloor} [{\rm gcd}(i, j) = 1]ij \\ &=\left(\frac{x(x+1)}{2}\right)^2 - \sum_{d = 2}^x d^2 f(\left\lfloor\frac{x}{d}\right\rfloor) \end{aligned}\]

这样,我们就能够递归地去求解当 \(x\) 较大时 \(f(x)\) 的值了。不难发现,该求解方法的时间复杂度和杜教筛是一样的,为 \(O(n^{\frac{2}{3}})\),且非常好写。

代码

#include<bits/stdc++.h>

using namespace std;

const int mod = 1000000007, inv2 = 500000004, inv6 = 166666668, up = 10000001;

int main() {
  function<int (int, int)> mul = [&] (int x, int y) {
    return (long long) x * y % mod;
  };
  function<void (int&, int)> add = [&] (int& x, int y) {
    x += y;
    if (x >= mod) {
      x -= mod;
    }
  };
  function<void (int&, int)> sub = [&] (int& x, int y) {
    x -= y;
    if (x < 0) {
      x += mod;
    }
  };
  vector<bool> is_prime(up, true);
  vector<int> phi(up), primes;
  phi[1] = 1;
  for (int i = 2; i < up; ++i) {
    if (is_prime[i]) {
      primes.push_back(i);
      phi[i] = i - 1;
    }
    for (auto v : primes) {
      int d = v * i;
      if (d >= up) {
        break;
      }
      is_prime[d] = false;
      if (i % v == 0) {
        phi[d] = mul(phi[i], v);
        break;
      } else {
        phi[d] = mul(phi[i], phi[v]);
      }
    }
  }
  for (int i = 2; i < up; ++i) {
    phi[i] = mul(mul(phi[i], i), i);
    add(phi[i], phi[i - 1]);
  }
  function<int (long long)> sum_pow2 = [&] (long long n) {
    n %= mod;
    return mul(mul(mul(n, n + 1), (n * 2 + 1)), inv6);
  };
  map<long long, int> value;
  function<int (long long)> f = [&] (long long n) {
    if (value.count(n)) {
      return value[n];
    } else {
      int result = 0;
      if (n < up) {
        result = phi[n];
      } else {
        int x = n % mod;
        x = mul(mul(x, x + 1), inv2);
        result = mul(x, x);
        for (long long i = 2, last; i <= n; i = last + 1) {
          last = n / (n / i);
          sub(result, mul((sum_pow2(last) - sum_pow2(i - 1) + mod) % mod, f(n / i)));
        }
      }
      return value[n] = result;
    }
  };
  long long n;
  scanf("%lld", &n);
  int answer = 0;
  for (long long i = 1, last; i <= n; i = last + 1) {
    last = n / (n / i);
    add(answer, mul(mul(mul((i + last) % mod, (last - i + 1) % mod), inv2), f(n / i)));
  }
  printf("%d\n", answer);
  return 0;
}

原文地址:https://www.cnblogs.com/ImagineC/p/10121395.html

时间: 2024-10-14 11:34:30

51nod1238. 最小公倍数之和 V3(莫比乌斯反演)的相关文章

51nod1238 最小公倍数之和 V3 莫比乌斯函数 杜教筛

题意:求\(\sum_{i = 1}^{n}\sum_{j = 1}^{n}lcm(i, j)\). 题解:因为是用的莫比乌斯函数求的,所以推导比大部分题解多...而且我写式子一般都比较详细,所以可能看上去很多式子,实际上是因为每一步都写了,几乎没有跳过的.所以应该都可以看懂的. 末尾的\(e\)函数是指的\(e[1] = 1\),\(e[x] = 0(x != 1)\)这样一个函数 \[\sum_{i = 1}^{n}\sum_{j = 1}^{n}lcm(i, j)\] \[\sum_{i

【51Nod 1237】最大公约数之和 V3 莫比乌斯反演+杜教筛

题意 求$\sum_{i=1}^{n}\sum_{j=1}^{n}(i,j)$ 枚举约数 $$ \begin{align} ans &=\sum_{d=1}^{n}\sum_{i=1}^{n}\sum_{j=1}^{n}[(i,j)=d] \ &=\sum_{d=1}^{n}\sum_{i=1}^{\lfloor \frac{n}{d} \rfloor}\sum_{j=1}^{\lfloor \frac{n}{d} \rfloor}[(i,j)=1] \ \end{align} $$ 利用

51nod1238 最小公倍数之和 V3

n<=1e10,求1<=i<=n,1<=j<=n,lcm(i,j)的和. 又是充满坎坷的简单题... Wait a minute 先打个miu和phi的表,以及一个暴力,随时检查式子! 来吧! $\sum_{i=1}^{n}\sum_{j=1}^{n}[i,j]$ $=\sum_{i=1}^{n}\sum_{j=1}^{n}ij(i,j)^{-1}$ $=\sum_{d=1}^{n}d^{-1}\sum_{i=1}^{n}\sum_{j=1}^{n}ij[(i,j)=d]$

[51nod1238] 最小公倍数之和 V3(杜教筛)

题面 传送门 题解 懒了--这里写得挺好的-- //minamoto #include<bits/stdc++.h> #define R register #define ll long long #define IT map<ll,int>::iterator #define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i) #define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i) #define go(

51 NOD 1238 最小公倍数之和 V3

原题链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1238 最近被51NOD的数论题各种刷……(NOI快到了我在干什么啊! 然后发现这题在网上找不到题解……那么既然A了就来骗一波访问量吧…… (然而并不会用什么公式编辑器,凑合着看吧…… Σ(1<=i<=n) Σ(1<=j<=n) i*j/gcd(i,j) =Σ(1<=d<=n) d * Σ(1<=i<=[n/d]) Σ(1&

51nod 1222 最小公倍数计数【莫比乌斯反演】

参考:https://www.cnblogs.com/SilverNebula/p/7045199.html 所是反演其实反演作用不大,又是一道做起来感觉诡异的题 转成前缀和相减的形式 \[ \sum_{i=1}^{n}\sum_{j=1}^{n}[\frac{i*j}{gcd(i,j)}\leq n] \] \[ \sum_{d=1}^{n}\sum_{i=1}^{\left \lfloor \frac{n}{d}\right \rfloor}\sum_{j=1}^{\left \lfloor

【51nod】1238 最小公倍数之和 V3

[题意]给定n,求Σi=1~nΣj=1~n lcm(i,j),n<=10^10. [算法]杜教筛 [题解] $ans=\sum_{i=1}^{n}\sum_{j=1}^{i}lcm(i,j)$ 令$g(n)=\sum_{i=1}\frac{n*i}{(n,i)}$,则要求g(n)的前缀和. $g(n)=n\sum_{d|n}\sum_{i=1}^{n}\frac{i}{d}[(n,i)=d]$ $g(n)=n\sum_{d|n}\sum_{i=1}^{n/d}i[(n/d,i)=1]$ $g(n

51Nod 最大公约数之和V1,V2,V3;最小公倍数之和V1,V2,V3

1040 最大公约数之和 给出一个n,求1-n这n个数,同n的最大公约数的和.比如:n = 6 1,2,3,4,5,6 同6的最大公约数分别为1,2,3,2,1,6,加在一起 = 15 输入 1个数N(N <= 10^9) 输出 公约数之和 输入样例 6 输出样例 15 题解 \[ \sum_{i=1}^n\gcd(i,n)=\sum_{d|n}d\varphi(n) \] 暴力搞就行了. 1188 最大公约数之和 V2 给出一个数N,输出小于等于N的所有数,两两之间的最大公约数之和. 相当于计

【51nod】1222 最小公倍数计数 莫比乌斯反演+组合计数

[题意]给定a和b,求满足a<=lcm(x,y)<=b && x<y的数对(x,y)个数.a,b<=10^11. [算法]莫比乌斯反演+组合计数 [题解]★具体推导过程参考:51nod1222 最小公倍数计数 过程运用到的技巧: 1.将所有i和j的已知因子提取出来压缩上届. 2.将带有μ(k)的k提到最前面,从而后面变成单纯的三元组形式. 最终形式: $$ans=\sum_{k=1}^{\sqrt n} \mu(k)  \sum_{d}    \sum_{i} \s