题目大意

给出一些数\(A_1,A_2,\cdots A_n\),求

\[\sum_{i=1}^{n}\sum_{j=1}^{n}\mathrm{lcm}(A_i,A_j)
\]

\(A_i,A_n\leq 50000\)

运用莫比乌斯反演思路

对于这种对多个数进行gcd、lcm统计的题,往往要用莫比乌斯反演。运用莫比乌斯反演的思路往往如下:

  1. 我们要求的\(g(x)\)是什么?
  2. 比较容易求的\(f(x)\)是什么?
  3. 如果我们要求的\(g(x)\)已知,则比较容易求的\(f(x)\)应当如何表达?
  4. 如果表达是以莫比乌斯反演公式的形式,则先求出\(f(x)\),然后反演出\(g(x)\)即可。

我们要求的\(g(x)\)是什么?

错误做法

根据我们的做题经验,\(g(x)\)表示最大公约数是\(x\)的数的对数,即

\[g(x)=\sum_{i=1}^n\sum_{j=1}^n [\gcd(A_i,A_j)=k]
\]

为什么可以利用它呢?因为

\[原式=\sum_{i=1}^{n}\sum_{j=1}^{n}\frac{A_i A_j}{\gcd(A_i,A_j)}\tag{1}
\]

提取出\(A_i,A_j\)得

\[原式=(\sum_{i=1}^n A_i)^2\sum_{i=1}^{n}\sum_{j=1}^{n}\frac{1}{\gcd(A_i,A_j)}
\]

OH,NO!这么化简是不对的。设\(f(x),g(x)\)为任意函数,则

\[\sum_{i=1}^{n}\sum_{j=1}^{n}f(i)g(j)=\sum_{i=1}^n f(i)\sum_{j=1}^n g(j)
\]

此式成立,因为函数\(f(i),g(j)\)的参数只关于一个变量。但是

\[\sum_{i=1}^n\sum_{j=1}^n f(i,j)g(i,j)\neq \sum_{i=1}^n\sum_{j=1}^n f(i,j)\sum_{i=1}^n\sum_{j=1}^n g(i,j)
\]

这就很荒谬了。函数\(f,g\)是同时关于\(i,j\)的函数。两个函数相乘时,里面的\((i,j)\)都应当是相等的,但化后的式子\(f,g\)内的\(i,j\)不相等时也乘起来了,这就错了。原式中,\(f(i,j)=A_i A_j\),\(g(i,j)=\frac{1}{\gcd(A_i,A_j)}\)。问题就出在这里。

正确做法

至少(1)式还是对的。因为\(\gcd(A_i,A_j)\)一定时,我们要求的是\(A_i A_j\)的和,所以

\[g(x)=\sum_{i=1}^n\sum_{j=1}^n A_i A_j[\gcd(A_i,A_j)=x]
\]

\(f(x)\)怎么求?

定义

\[f(x)=\sum_{i=1}^n\sum_{j=1}^n A_i A_j[\gcd(A_i,A_j)=kx]\tag{2}$$$$=\sum_{i=1}^n\sum_{j=1}^n A_i A_j[x|A_i,x|A_j]$$$$=\sum_{x|A_i}\sum_{x|A_j}A_i A_j$$$$=(\sum_{x|A_i}A_i)^2\tag{3}
\]

(2)式即能体现莫比乌斯函数的性质。

运用(3)求\(f(x)\)。

如何迅速地找到所有满足条件的\(A_i\)?

建立一个维护A个数的桶数组即可。

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std; #define ll long long const int MAX_N = 50010;
int Mu[MAX_N];
ll F[MAX_N], G[MAX_N], ExistCnt[MAX_N];
ll N, MaxA; void GetMu(int *mu, int n)
{
static int prime[MAX_N];
static bool NotPrime[MAX_N];
int primeCnt = 0;
Mu[1] = 1;
for (int i = 2; i <= n; i++)
{
if (!NotPrime[i])
{
prime[primeCnt++] = i;
Mu[i] = -1;
}
for (int j = 0; j <= primeCnt; j++)
{
if (i*prime[j] > n)
break;
NotPrime[i*prime[j]] = true;
if (i%prime[j] == 0)
{
mu[i*prime[j]] = 0;
break;
}
else
mu[i*prime[j]] = -mu[i];
}
}
} void GetF()
{
for (int cd = 1; cd <= MaxA; cd++)
{
ll sum = 0;
for (int k = 1; k <= MaxA / cd; k++)
sum += cd*k*ExistCnt[cd*k];
F[cd] = sum*sum;
}
} void GetG()
{
for (int gcd = 1; gcd <= MaxA; gcd++)
for (int k = 1; k <= MaxA / gcd; k++)
G[gcd] += F[gcd*k] * Mu[k];
} ll Solve()
{
ll ans = 0;
for (int gcd = 1; gcd <= MaxA; gcd++)
ans += G[gcd] / gcd;
return ans;
} int main()
{
ll a;
scanf("%lld", &N);
for (int i = 1; i <= N; i++)
{
scanf("%lld", &a);
ExistCnt[a]++;
MaxA = max(MaxA, a);
}
GetMu(Mu, MaxA);
GetF();
GetG();
cout << Solve() << endl;
return 0;
}

luogu3911 最小公倍数之和的更多相关文章

  1. luogu3911 最小公倍数之和(莫比乌斯反演)

    link 给定\(A_1,A_2,\dots,A_N\),求\(\sum_{i=1}^N\sum_{j=1}^Nlcm(A_i,A_j)\) \(1\le N\le 50000;1\le A_i\le ...

  2. 51NOD 1238 最小公倍数之和 V3 [杜教筛]

    1238 最小公倍数之和 V3 三种做法!!! 见学习笔记,这里只贴代码 #include <iostream> #include <cstdio> #include < ...

  3. 51nod1363 最小公倍数之和

    题目描述 给出一个n,求1-n这n个数,同n的最小公倍数的和. 例如:n = 6,1,2,3,4,5,6 同6的最小公倍数分别为6,6,6,12,30,6,加在一起 = 66. 由于结果很大,输出Mo ...

  4. 51nod 1238 最小公倍数之和 V3

    51nod 1238 最小公倍数之和 V3 求 \[ \sum_{i=1}^N\sum_{j=1}^N lcm(i,j) \] \(N\leq 10^{10}\) 先按照套路推一波反演的式子: \[ ...

  5. 51nod 1190 最小公倍数之和 V2

    给出2个数a, b,求LCM(a,b) + LCM(a+1,b) + .. + LCM(b,b). 例如:a = 1, b = 6,1,2,3,4,5,6 同6的最小公倍数分别为6,6,6,12,30 ...

  6. 51nod 1363 最小公倍数之和 ——欧拉函数

    给出一个n,求1-n这n个数,同n的最小公倍数的和.例如:n = 6,1,2,3,4,5,6 同6的最小公倍数分别为6,6,6,12,30,6,加在一起 = 66. 由于结果很大,输出Mod 1000 ...

  7. 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 ...

  8. BNU 12846 LCM Extreme 最小公倍数之和(线性欧拉筛选+递推)

    LCM Extreme Time Limit: 3000ms Memory Limit: 131072KB   This problem will be judged on UVALive. Orig ...

  9. 51 NOD 1238 最小公倍数之和 V3

    原题链接 最近被51NOD的数论题各种刷……(NOI快到了我在干什么啊! 然后发现这题在网上找不到题解……那么既然A了就来骗一波访问量吧…… (然而并不怎么会用什么公式编辑器,写得丑也凑合着看吧…… ...

随机推荐

  1. vs2008 启动IE浏览器 出现DW20.exe占用大量cpu 服务器iis 异常调试

    DW20.exe占用大量cpu 服务器iis运行出现异常想查一下故障原因,发现有好几个DW20.exe进程,每个占用20%左右的cpu,在任务管理器中将其终止后,它又自动运行起来了 查了一下DW20. ...

  2. xml之基本操作

    XML:Extensible Markup Language(可扩展标记语言)的缩写,是用来定义其它语言的一种元语言,其前身是SGML(Standard Generalized Markup Lang ...

  3. “阻塞”与"非阻塞"与"同步"与“异步"

    链接:http://www.zhihu.com/question/19732473/answer/20851256来源:知乎 “阻塞”与"非阻塞"与"同步"与“ ...

  4. sql的padleft

    /* SELECT dbo.fn_PadLeft('8', '0', 6) */ create function fn_PadLeft(@num nvarchar(16),@paddingChar c ...

  5. 水仙花数------"水仙花数 "是指一个三位数,其各位数字立方和等于该数本身。(for循环的嵌套)

    package com.zuoye.test;//打印出所有的 "水仙花数 ",所谓 "水仙花数 "是指一个三位数,//其各位数字立方和等于该数本身.//例如: ...

  6. Matlab矩阵填充--Matlab interp2

    Matlab interp2 为Matlab的矩阵填充函数, 填充关系: x=1:11; y=1:13; x1=1:0.1:12; y1=1:0.1:14; [x2,y2]=meshgrid(x1,y ...

  7. idea搭建第一个springboot

    1.打开idea开发工具,在菜单栏选择File-->New-->Project...-->Spring Initializer说明:社区版的idea是没有Spring Initial ...

  8. Linux删除重复内容命令uniq笔记

    针对文本文件,有时候我们需要删除其中重复的行.或者统计重复行的总次数,这时候可以采用Linux系统下的uniq命令实现相应的功能. 语法格式:uniq [-ic] 常用参数说明: -i 忽略大小写 - ...

  9. 【剑指Offer】17、树的子结构

      题目描述:   输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构)   解题思路:   要查找树A中是否存在和树B结构一样的子树,我们可以分为两步:第一步, ...

  10. 45.mapping建立、修改

    主要知识点 1.如何建立索引 2.修改mapping 3.测试mapping         一.如何建立索引 语法 PUT /website { "mappings": { &q ...