题意:求\(\sum_{i = 1}^{n}\sum_{j = 1}^{n}lcm(i, j)\).

  题解:虽然网上很多题解说用mu卡不过去,,,不过试了一下貌似时间还挺充足的,。。也许有时间用phi试试?

  因为是用的莫比乌斯函数求的,所以推导比大部分题解多。。。而且我写式子一般都比较详细,所以可能看上去很多式子,实际上是因为每一步都写了,几乎没有跳过的。所以应该都可以看懂的。

  末尾的\(e\)函数是指的\(e[1] = 1\),\(e[x] = 0(x != 1)\)这样一个函数

  $$\sum_{i = 1}^{n}\sum_{j = 1}^{n}lcm(i, j)$$

  $$\sum_{i = 1}^{n} \sum_{i = 1}^{n} \frac{ij}{gcd(i, j)}$$

  枚举\(gcd\)

  $$\sum_{d = 1}^{n} \sum_{i = 1}^{\lfloor {\frac{n}{d}} \rfloor} \sum_{j = 1}^{\lfloor {\frac{n}{d}} \rfloor}[gcd(i, j) == d] \frac{ij}{d}$$

  因为\((\frac{ijd^2}{d} = ijd)\),所以:

  $$\sum_{d = 1}^{n} \sum_{i = 1}^{\lfloor {\frac{n}{d}} \rfloor} \sum_{j = 1}^{\lfloor {\frac{n}{d}} \rfloor}[gcd(i, j) == d] ijd$$

  $$\sum_{d = 1}^{n}d\sum_{i = 1}^{\lfloor {\frac{n}{d}} \rfloor} \sum_{j = 1}^{\lfloor {\frac{n}{d}} \rfloor}ij[gcd(i, j) == 1]$$

  $$\sum_{d = 1}^{n} d \sum_{i = 1}^{\lfloor {\frac{n}{d}} \rfloor} \sum_{j = 1}^{\lfloor {\frac{n}{d}} \rfloor} ij \sum_{k | gcd(i, j)} \mu(k)$$

  枚举k,再枚举k的倍数。

  $$\sum_{d = 1}^{n}d\sum_{k = 1}^{\lfloor {\frac{n}{d}} \rfloor}\mu(k) \sum_{i = 1}^{\lfloor {\frac{n}{dk}} \rfloor}ik \sum_{j = 1}^{\lfloor {\frac{n}{dk}} \rfloor}jk$$

  设\(S(n) = \sum_{i = 1}^{n}i\)

  $$\sum_{d = 1}^{n}d \sum_{k = 1}^{\lfloor {\frac{n}{d}} \rfloor} \mu(k) k ^ 2 S(\frac{n}{dk})$$

  枚举\(T = dk\)

  $$\sum_{T = 1}^{n} S(\frac{n}{T})^ 2 \sum_{k | T} \mu(k) k ^ 2 \frac{T}{k}$$

  $$\sum_{T = 1}^{n} S(\frac{n}{T})^ 2 \sum_{k | T} \mu(k) kT$$

  $$\sum_{T = 1}^{n} S(\frac{n}{k})^ 2 \cdot T \sum_{k | T} \mu(k)k$$

  设\(f(T) = T\sum_{k | T} \mu(k) k\),卷上\(id^2\),因为\(S(\frac{n}{k})\)可以数论分块,所以我们只需要快速求出区间\([l, r]\)内的\(f\)之和即可,显然求出\(f\)的前缀和即可解决问题

  $$(f * id^2)(n) = \sum_{i |n}f(i) \frac{n2}{i2}=\sum_{i | n}i \sum_{k | i} \mu(k) k \frac{n ^ 2}{i ^ 2}$$

  $$\sum_{i | n}\sum_{k | i} \mu(k)k\frac{n ^ 2}{i} = n \sum_{i | n}\sum_{k | i} \mu(k) k \frac{n}{i}$$

  设$$h(i) = \sum_{k | i} \mu(k)k$$,则原式:

  $$n \sum_{i | n} h(i) \frac{n}{i} = n (h * id)(n)$$

  $$(f * id ^ 2)(n) = n (h * id)(n)$$

  $$h(n) = \sum_{k | n}\mu(k)k = (\mu \cdot id) * 1$$

  $$f * id ^ 2 = n [(\mu \cdot id) * 1 * id] = n[(\mu \cdot id) * id * 1]$$

  其中$$(\mu \cdot id) * id = \sum_{i | n} \mu(i) i \frac{n}{i} = n \sum_{i | n}\mu(i) = e$$

  所以

  $$n[(\mu \cdot id) * id * 1] = n[e * 1] = n$$

  带入杜教筛的式子:

  $$g(1)S(n) = \sum_{i = 1}^{n} (f * g)(i) - \sum_{i = 2}^{n}g(i)S(\frac{n}{i})$$

  $$= \sum_{i = 1}^{n}i - \sum_{i = 2}^{n}i ^ 2 S(\frac{n}{i})$$

  然后直接上杜教就可以了.

  其实还有一个问题。。。一开始预处理的前缀和怎么求?

  要知道前缀和,首先要求出\(f\).

  因为\(f(T) = T\sum_{k | T} \mu(k) k\),所以如果我们可以快速求出\(\sum_{k | T}\mu(k)k\),然后就只需要再\(O(n)\)的乘上\(T\)就可以了.

  我们先预处理出\(\mu(k)\),然后对于每一个\(k\),枚举它的倍数,统计贡献。那么复杂度为 \(\frac{n}{1} + \frac{n}{2} + ... + \frac{n}{n} = nlogn\)(此处的\(n\)为原题面的\(\frac{2}{3}\)次方,即要预处理的\(f\)个数)

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define R register int
  4. #define LL long long
  5. #define RL register LL
  6. #define AC 3000
  7. #define ac 5000000
  8. #define p 1000000007LL
  9. //#define h(x) ((x <= block) ? sum[x] : S[n / x])
  10. LL n, ans, block;
  11. LL mu[ac], S[AC], sum[ac], inv[AC];
  12. int pri[ac], tot;
  13. bool z[ac], vis[AC];
  14. inline LL h(LL x)
  15. {
  16. return ((x <= block) ? sum[x] : S[n / x]);
  17. }
  18. inline void up(LL & a, LL b)
  19. {
  20. a += b;
  21. if(a >= p) a -= p;
  22. if(a <= -p) a += p;
  23. }
  24. LL count(LL l, LL r){
  25. return (r - l + 1) % p * ((r + l) % p) % p * inv[2] % p;
  26. }
  27. void pre()
  28. {
  29. scanf("%lld", &n), block = pow(n, 0.66666);
  30. mu[1] = 1;
  31. for(R i = 2; i <= block; i ++)
  32. {
  33. if(!z[i]) pri[++ tot] = i, mu[i] = -1;
  34. for(R j = 1; j <= tot; j ++)
  35. {
  36. int now = pri[j];
  37. if(i * now > block) break;
  38. z[i * now] = true;
  39. if(!(i % now)) break;
  40. mu[i * now] = - mu[i];
  41. }
  42. }
  43. inv[1] = 1;
  44. for(R i = 2; i <= 10; i ++) inv[i] = (p - p / i) * inv[p % i] % p;
  45. for(R i = 1; i <= block; i ++)//枚举mu(i)
  46. for(R j = 1; j; j ++)//枚举i的倍数
  47. {
  48. if(j * i > block) break;
  49. up(sum[i * j], mu[i] * i % p);
  50. }
  51. for(R i = 1; i <= block; i ++) sum[i] = sum[i] * i % p;
  52. for(R i = 1; i <= block; i ++) up(sum[i], sum[i - 1]);//算出f数组后还要统计前缀和
  53. }
  54. LL get(LL x)
  55. {
  56. x %= p;
  57. return x * (x + 1) % p * (2 * x + 1) % p * inv[6] % p;
  58. }
  59. void cal(LL x)
  60. {
  61. if(x <= block || vis[n / x]) return ;
  62. LL rnt = count(1, x);
  63. for(RL i = 2, lim, now; i <= x; i = lim + 1)
  64. {
  65. lim = x / (x / i), now = x / i, cal(now);
  66. up(rnt, - ((get(lim) - get(i - 1)) % p * h(now) % p));
  67. }
  68. S[n / x] = rnt, vis[n / x] = true;
  69. }
  70. void work()
  71. {
  72. for(RL i = 1, lim, now, x; i <= n; i = lim + 1)
  73. {
  74. lim = n / (n / i), now = n / i, x = count(1, now);
  75. up(ans, (x % p * x % p * ((h(lim) - h(i - 1)) % p) % p));
  76. }
  77. printf("%lld\n", (ans + p) % p);
  78. }
  79. int main()
  80. {
  81. //freopen("in.in", "r", stdin);
  82. pre();
  83. cal(n);
  84. work();
  85. // fclose(stdin);
  86. return 0;
  87. }

51nod1238 最小公倍数之和 V3 莫比乌斯函数 杜教筛的更多相关文章

  1. 51Nod.1237.最大公约数之和 V3(莫比乌斯反演 杜教筛 欧拉函数)

    题目链接 \(Description\) \(n\leq 10^{10}\),求 \[\sum_{i=1}^n\sum_{j=1}^ngcd(i,j)\ mod\ (1e9+7)\] \(Soluti ...

  2. 51nod 1244 莫比乌斯函数之和 【莫比乌斯函数+杜教筛】

    和bzoj 3944比较像,但是时间卡的更死 设\( f(n)=\sum_{d|n}\mu(d) g(n)=\sum_{i=1}^{n}f(i) s(n)=\sum_{i=1}^{n}\mu(i) \ ...

  3. 【题解】最大公约数之和 V3 51nod 1237 杜教筛

    题目传送门 http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1237 数学题真是做的又爽又痛苦,爽在于只要推出来公式基本上就 ...

  4. [CSP-S模拟测试]:123567(莫比乌斯函数+杜教筛+数论分块)

    题目传送门(内部题92) 输入格式 一个整数$n$. 输出格式 一个答案$ans$. 样例 样例输入: 样例输出: 数据范围与提示 对于$20\%$的数据,$n\leqslant 10^6$. 对于$ ...

  5. 51nod 1220 约数之和【莫比乌斯反演+杜教筛】

    首先由这样一个式子:\( d(ij)=\sum_{p|i}\sum_{q|j}[gcd(p,q)==1]\frac{pj}{q} \)大概感性证明一下吧我不会证 然后开始推: \[ \sum_{i=1 ...

  6. bzoj 4916: 神犇和蒟蒻【欧拉函数+莫比乌斯函数+杜教筛】

    居然扒到了学长出的题 和3944差不多(?),虽然一眼看上去很可怕但是仔细观察发现,对于mu来讲,答案永远是1(对于带平方的,mu值为0,1除外),然后根据欧拉筛的原理,\( \sum_{i=1}^{ ...

  7. bzoj 3512: DZY Loves Math IV【欧拉函数+莫比乌斯函数+杜教筛】

    参考:http://blog.csdn.net/wzf_2000/article/details/54630931 有这样一个显然的结论:当\( |\mu(n)|==1 \)时,\( \phi(nk) ...

  8. 51nod 1227 平均最小公倍数【欧拉函数+杜教筛】

    以后这种题能用phi的就不要用mu-mu往往会带着个ln然后被卡常致死 把题目要求转换为前缀和相减的形式,写出来大概是要求这样一个式子: \[ \sum_{i=1}^{n}\sum_{j=1}^{i} ...

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

    题意 题目链接 Sol 不想打公式了,最后就是求一个 \(\sum_{i=1}^n ig(\frac{N}{i})\) \(g(i) = \sum_{i=1}^n \phi(i) i^2\) 拉个\( ...

随机推荐

  1. Django模型层:多表查询

    一 创建模型 实例:我们来假定下面这些概念,字段和关系 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息.作者详情模型和作者模型之间是一对一的关 ...

  2. 【转】RobotFrameWork+APPIUM实现对安卓APK的自动化测试----第二篇【原理】

    接着上一篇,我们开始聊聊APPIUM的框架和运行模式.废话不多说直接上图. 1.首先自动化脚本通过RobotFrameWork将命令传递给Appium的客户端: 2.然后[Appium的客户端]将接受 ...

  3. Mac下布置appium环境

    1.下载或者更新Homebrew:homebrew官网 macOS 不可或缺的套件管理器 $ /usr/bin/ruby -e "$(curl -fsSL https://raw.githu ...

  4. json_encode替代函数

    <?php   function jsonEncode($var) {     if (function_exists('json_encode')) {         return json ...

  5. Linux 安装ActiveMQ(使用Mac远程访问)

    阅读本文需要安装JDK 一 ActiveMQ简介 activemq是用java语言编写的一款开源消息总线 activemq是apache出品 activemq消息的传递有两种类型 一种是点对点: 即一 ...

  6. redis主从配置+sentinel哨兵

    redis主从配置+sentinel哨兵 1:编译环境准备 1.1环境确认 Redis是一个开源.支持网络.基于内存.键值对存储数据库,使用ANSI C编写.所以在搭建Redis服务器时需要C语言的编 ...

  7. 【转】: 塞尔达组在GDC2017演讲的文字翻译:显示的力量

      塞尔达系列推出新作的时候,美术风格都有明显变化.本作的风格比起写实,笔触轻快变化幅度大是其特征.2011年公开的技术演示中,画面风格要更加写实.最终版则更接近于卡通.5年里到底发生了什么呢? ▲2 ...

  8. Leetcode_2. Add_Two_Number

    2. Add_Two_Number 用两个非空链表分别表示两个非负整数,链表的节点表示数字的位,链表头表示数字的低位,链表尾表示数字高位.求两个链表所表示数字的和. 比如: Input: (2 -&g ...

  9. 《linux内核分析》 第一周

    20135130  王川东 计算机是如何工作的? 计算机的基本原理是存储程序和程序控制.预先要把指挥计算机如何进行操作的指令序列(称为程序)和原始数据通过输入设备输送到计算机内存贮器中.每一条指令中明 ...

  10. Java 学习笔记 ------第三章 基础语法

    本章学习目标: 认识类型与变量 学习运算符的基本使用 了解类型转换细节 运用基本流程语法 一.类型(基本类型) 所谓基本类型,就是在使用时,得考虑一下数据用多少内存长度存比较经济,利用程序语法告诉JV ...