题目大意

给出一些数\(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. indeed 5.13 第二次网测

    题目描述,我找不见了,大概写一下想法和代码吧. 1. 没有看 2. 由于数据范围很小,就是简单的枚举,求全排列,然后更新答案. #include<bits/stdc++.h> #defin ...

  2. Android 打开设置界面或者WiFi连接界面

    1.使用APP打开系统的设置界面或者WiFi连接界面 startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS)); //直接进入手机中的wifi网 ...

  3. 关于VirtualBox与锐捷冲突导致锐捷不断掉线的问题的解决办法

    和VM一样,virtualBox也是和锐捷冲突,网上有一些方法是禁用虚拟网卡,但是还是会导致锐捷客户端掉线,除非使用wifi 第一个解决办法: 偶然看到一个解决办法是,在锐捷客户端登陆之后,打开任务管 ...

  4. java ---书写自己的名字

    public class hello { public static void main(String[] args) { // TODO 自动生成的方法存根 System.out.println(& ...

  5. redis 主从复制 redis 探索

    http://blog.csdn.net/column/details/12804.html

  6. 读书笔记「Python编程:从入门到实践」_7.用户输入和while循环

    7.1 函数input()的工作原理 函数input() 让程序暂停运行,等待用户输入一些文本.获取用户输入后,Python将其存储在一个变量中,以方便你使用. message = input(&qu ...

  7. Git更新代码

    此次更新,创建新的文件与文件夹,并且删除了原有文件 通过“git status” 命令查看当前变更.通过变更信息可以看出,删除了test_case.py文件.这个删除只是在项目目录下进行删除,Git对 ...

  8. h5调用app中写好的的方法

    做h5页面的时候,总会遇到些不能解决的问题于是就要与app做一些交互, app那边编辑好的方法后我们怎么用js语法去调用app编写好的方法 if(this.$winInfo.shebei == 1){ ...

  9. java实现简单窗体小游戏----球球大作战

    java实现简单窗体小游戏----球球大作战需求分析1.分析小球的属性: ​ 坐标.大小.颜色.方向.速度 2.抽象类:Ball ​ 设计类:BallMain—创建窗体 ​ BallJPanel—画小 ...

  10. Scrapy处理200-300范围之外的响应代码

    HttpErrorMiddleware 类scrapy.spidermiddlewares.httperror.HttpErrorMiddleware 过滤掉不成功(错误)的HTTP响应,以便蜘蛛不必 ...