OI中的莫比乌斯反演


莫比乌斯函数

想要学习莫比乌斯反演,首先要学习莫比乌斯函数

定义

莫比乌斯函数用\(\mu(x)\)表示。如果\(x\)是\(k\)个不同质数的积,则\(\mu(x) = (-1)^k\),否则\(\mu(x) = 0\)(此时\(x\)一定是某个或某些平方数的倍数)。\(x = 1\)时,相当于\(x\)由\(0\)个不同质数组成,所以\(\mu(1) = 1\)。

\[\mu(x)=\left\{
\begin{array}{rcl}
1 & & {x = 1}\\
(-1)^k& & {x = p_1p_2...p_k}\\
0 & & {else}\\
\end{array} \right.
\]

性质

莫比乌斯函数有如下性质:

  1. 莫比乌斯函数是一个积性函数,即对于任意互质的两个数\(x, y\),有\(\mu(xy) = \mu(x) \times \mu(y)\)
  2. 对于任意正整数\(n\)有$$\sum_{d | n} \mu(d) = \left{\begin{array}{rcl}1 && {n = 1} \ 0 && {n > 1} \end{array}\right.$$
  3. 对于任意正整数\(n\)有$$\sum_{d|n}\frac{\mu(d)}{d} = \frac{\phi(n)}{n}$$

证明

// 证明嘛……不看也罢。本文重点在“莫比乌斯反演在OI中的应用”,大胆猜想,不用证明,2333

  1. 莫比乌斯函数的积性:显然,若\(x\)、\(y\)中有一个含有平方数因子,则\(\mu(x)\)、\(\mu(y)\)中有一个为\(0\),相乘得\(0\),而\(xy\)也含有平方数因子,所以它的\(\mu(xy) = 0 = \mu(x) * \mu(y)\)。若\(x\)、\(y\)中都不含有平方数因子,又因为\(x\)、\(y\)互质,所以乘积\(xy\)也不含有平方数因子。设\(x\)有\(m\)个不同质因子,\(y\)有\(n\)个,则\(xy\)有\(n + m\)个,则\(\mu(xy) = (-1)^{n + m}= (-1)^n \times (-1)^m = \mu(x) \times \mu(y)\)。
  2. 当\(n = 1\)时显然。当\(n > 1\)时,\(n\)可以分解为\(p_1^{a_1}p_2^{a_2}...p_k^{a_k}\)。在\(n\)的所有因子\(d\)中,\(\mu\)值不为\(0\)的只有没有平方数因子的\(d\),即由\(p_1...p_k\)中任意多个质因数直接相乘得到的乘积。则有:$$\sum_{d|n}\mu(d) = C_k^0 - C_k^1 + C_k^2 - ... + (-1)kC_kk = \sum_{i = 0}{k}(-1)iC_k^i$$只需证明这个式子等于\(0\)。根据二项式定理,\((x + y)^n = \sum_{i=0}^{n}C_n^ix^iy^{n-i}\),令\(x = -1, y = 1\),代入得证。
  3. \(\sum_{d|n}\phi(d) = n\)(证明传送门),而根据下面要讲的莫比乌斯反演定理,直接把\(F(x) = x, f(x) = \phi(x)\)代入即可。

莫比乌斯反演定理

内容

莫比乌斯反演定理的内容:

\[F(n) = \sum_{d|n}f(d) \Rightarrow f(n) = \sum_{d|n}\mu(d)F(\frac{n}{d})
\]

\[F(n) = \sum_{n|d}f(d) \Rightarrow f(n) = \sum_{n|d}\mu(\frac{d}{n})F(d)
\]

证明

懒得打这么多公式了……证明传送门

莫比乌斯反演的应用

BZOJ 2301 Problem b

对于给出的n个询问,每次求有多少个数对\((x,y)\),满足\(a≤x≤b\),\(c≤y≤d\),且\(gcd(x,y) = k\)。

\(1≤n≤50000, 1≤a≤b≤50000, 1≤c≤d≤50000, 1≤k≤50000.\)

要求满足条件的\(a≤x≤b\),\(c≤y≤d\)的数对个数,根据容斥原理,就是求满足条件的“\(1≤x≤b, 1≤y≤d\)的数对个数 - \(1≤x<a\),\(c≤y≤d\)的数对个数 - \(a≤x≤b\),\(1≤y<c\)的数对个数 + \(1≤x<a\),\(1≤y<c\)的数对个数”。

实际上,这道题还有一个更简单的、不用容斥原理的版本——BZOJ1101,可惜是权限题 =_=|||

而\(1≤x≤a, 1≤y≤b, gcd(x, y) = k\)等价于\(1≤x≤\lfloor\frac{a}{k}\rfloor\),\(1≤y≤\lfloor\frac{b}{k}\rfloor, gcd(\frac{x}{k}, \frac{y}{k}) = 1\)。

那么现在问题就变得简单了——求有多少数对\((x,y)\),满足\(1≤x≤a\),\(1≤y≤b\)且\(gcd(x, y) = 1\)。

设\(F(n)\)为\(1≤x≤a, 1≤y≤b, n | gcd(x, y)\)的点对\((x,y)\)的个数,

\(f(n)\)为\(1≤x≤a, 1≤y≤b, gcd(x, y) = n\)的点对\((x, y)\)个数。

显然,\(F(n) = \lfloor\frac{a}{n}\rfloor\lfloor\frac{b}{n}\rfloor\),\(n > \min(a, b)\)时,\(F(n) = f(n) = 0\)。

可以看出:$$F(n) = \sum_{n | d}f(d)$$

则根据莫比乌斯反演定理:$$f(n) = \sum_{n|d}\mu(\frac{d}{n})F(d) = \sum_{n|d}\mu(\frac{d}{n}) \lfloor\frac{a}{d}\rfloor\lfloor\frac{b}{d}\rfloor$$

我们最后要求的是\(f(1)\),所以代入\(n = 1\):

\[f(1) = \sum_{d = 1}^{+\infty}\mu(d)F(d) = \sum_{d = 1}^{min(a, b)}\mu(d) \lfloor\frac{a}{d}\rfloor\lfloor\frac{b}{d}\rfloor
\]

枚举\(d\)就可以\(O(n)\)求了,但是还有多组数据,这个复杂度太大。接下来我们要继续优化。

考虑这个问题:\(n\)为正整数,\(d\)为\([1, n]\)整数,那么\(\lfloor\frac{n}{d}\rfloor\)最多有多少种取值?

可以分类讨论:当\(d \le \sqrt n\),假设每个\(d\)都对应一个\(\lfloor\frac{n}{d}\rfloor\),则有\(\sqrt n\)个取值;当\(d > \sqrt n\),则\(\lfloor\frac{n}{d}\rfloor < \sqrt n\),则最多也只有\(\sqrt n\)个取值,因此取值数不超过\(2\sqrt n\)。

那么\(\lfloor\frac{a}{d}\rfloor\lfloor\frac{b}{d}\rfloor\)有多少取值呢?

emmm……实际上,最多有\(2(\sqrt a + \sqrt b)\)种取值。

我没有在网上找到严谨的数学证明,于是我在这里写个自创的不是非常数学的证明:

橙色折线是\(\lfloor\frac{b}{d}\rfloor\)随d变化的图像,蓝色折线\(\lfloor\frac{a}{d}\rfloor\)随d变化的图像。橙色水平线段总数\(\sqrt b\),蓝色水平线段总数是\(\sqrt a\),设\(a < b\)则橙色折线变化更频繁。

\(\lfloor\frac{a}{d}\rfloor\lfloor\frac{b}{d}\rfloor\)的取值种数即每一段蓝色水平线段对应的橙色水平线段数之和。假如图中每条绿色虚线对应的都恰好是橙色折线中的拐点,取值总数是橙色水平线段总数,即\(2\sqrt b\)。而实际上不一定总会对齐,每当绿色虚线对应上橙色折线中的一条水平线段中间的某个位置,则相当于右边的那截蓝色水平线段多对应了一截橙色水平线段。绿色线段数即蓝色折线拐点数,为\(2\sqrt a\)。

所以总取值数是\(2\sqrt a + 2\sqrt b\)。

回到上面的那个式子:\(f(1) = \sum_{d = 1}^{min(a, b)}\mu(d) \lfloor\frac{a}{d}\rfloor\lfloor\frac{b}{d}\rfloor\),我们枚举\(\lfloor\frac{a}{d}\rfloor\lfloor\frac{b}{d}\rfloor\)的取值(共\(2\sqrt a + 2\sqrt b\)种),且预处理\(\mu(d)\)的前缀和,则一次询问的复杂度是\(O(\sqrt n)\)。

至于代码实现——

枚举\(\lfloor\frac{a}{d}\rfloor\lfloor\frac{b}{d}\rfloor\)取值的代码:

if(a > b) swap(a, b);
for(int i = 1, last = 0; i <= a; i = last + 1){
last = min(a / (a / i), b / (b / i));
ans += (ll)(a / i) * (b / i) * (sum[last] - sum[i - 1]);
}

\(O(n)\)预处理\(\mu(d)\)前缀和的代码(参考贾志鹏 线性筛):

void getmu(){
mu[1] = sum[1] = 1;
for(int i = 2; i <= N; i++){
if(!notprime[i]) mu[i] = -1, prime[++tot] = i;
for(int j = 1; j <= tot && i * prime[j] <= N; j++){
notprime[i * prime[j]] = 1;
if(i % prime[j]) mu[i * prime[j]] = -mu[i];
else{
mu[i * prime[j]] = 0;
break;
}
}
sum[i] = sum[i - 1] + mu[i];
}
}

BZOJ 1101 完整代码

BZOJ 2301 完整代码

BZOJ 2820 YY的GCD

\(T\)组数据,给定\(a, b\),求\(1<=x<=a, 1<=y<=b\)且\(gcd(x, y)\)为质数的\((x, y)\)有多少对。

这道题和上面的有些类似,也可以设

\(F(n)\)为\(1≤x≤a, 1≤y≤b, n | gcd(x, y)\)的点对\((x,y)\)的个数,

\(f(n)\)为\(1≤x≤a, 1≤y≤b, gcd(x, y) = n\)的点对\((x, y)\)个数。

则仍然有$$f(n) = \sum_{n|d}\mu(\frac{d}{n}) \lfloor\frac{a}{d}\rfloor\lfloor\frac{b}{d}\rfloor$$

那么枚举质数\(p\),答案可表示为

\[\begin{align*}
ans &= \sum_{p}^{min(a, b)}\sum_{p|d}\mu(\frac{d}{p}) \lfloor\frac{a}{d}\rfloor\lfloor\frac{b}{d}\rfloor\\
&= \sum_{p}^{min(a, b)}\sum_{i = 1}^{min(a, b)}\mu(i) \lfloor\frac{a}{pi}\rfloor\lfloor\frac{b}{pi}\rfloor\\
\end{align*}\]

设\(t = pi\),代入得:

\[\begin{align*}
ans &= \sum_{p}^{min(a, b)}\sum_{p|t}^{min(a, b)}\mu(\frac{t}{p}) \lfloor\frac{a}{t}\rfloor\lfloor\frac{b}{t}\rfloor\\
&= \sum_{t = 1}^{min(a, b)}\sum_{p | t}^{min(a, b)}\mu(\frac{t}{p}) \lfloor\frac{a}{t}\rfloor\lfloor\frac{b}{t}\rfloor\\
&= \sum_{t = 1}^{min(a, b)}\lfloor\frac{a}{t}\rfloor\lfloor\frac{b}{t}\rfloor\sum_{p | t}^{min(a, b)}\mu(\frac{t}{p})
\end{align*}\]

我们知道\(\lfloor\frac{a}{t}\rfloor\lfloor\frac{b}{t}\rfloor\)的取值不超过\(2(\sqrt a + \sqrt b)\)种,那么如果预处理\(\sum_{p}^{min(a, b)}\mu(\frac{t}{p})\)关于t的前缀和,就可以\(O(\sqrt n)\)出解了。

预处理这个前缀和可以筛出素数后对每个素数枚举它的倍数、更新对应的\(\sum_{p}^{min(a, b)}\mu(\frac{t}{p})\)。因为处理每个素数均摊\(O(\log n)\),而一共约有\(O(\frac{n}{\log n})\)个素数,所以预处理前缀和的总复杂度是\(O(n)\)。

BZOJ 2820 完整代码

BZOJ 3529 数表

令\(F(i)\)为\(i\)的约数和,\(q\)次给定\(n\), \(m\), \(a\), 求

\[\sum_{1 \le i \le n, 1 \le j \le m, F(\gcd(i, j)) \le a} F(\gcd(i, j)) \mod 2^{31}
\]

数据范围:\(n, m, \le 10^5, a \le 10^9, q \le 2\times 10^4\)

\(F(gcd(i, j)) \le a\)的限制不好处理,所以我们先假设没有这条限制,问题变为求$$\sum_{1 \le i \le n, 1 \le j \le m} F(gcd(i, j)) \mod 2^{31}$$

和前面几道题一样,我们可以设\(g(x)\)为\(1 \le i \le n, 1 \le j \le m, \gcd(i, j) = 1\)的数对\((i, j)\)的个数,则有:

\[g(i) = \sum_{i|d} \mu(\frac{d}{i}) \lfloor\frac{n}{d}\rfloor\lfloor\frac{m}{d}\rfloor
\]

\(F(i)\)可以用线性筛预处理出来,则答案\(ans\)就是

\[\begin{align*}
ans &= \sum_{i = 1}^{min(n, m)}F(i)g(i)\\
&= \sum_{i = 1}^{min(n, m)} F(i)\sum_{i|d}\lfloor\frac{n}{d}\rfloor\lfloor\frac{m}{d}\rfloor\\
&= \sum_{d=1}^{min(n, m)}\lfloor\frac{n}{d}\rfloor\lfloor\frac{m}{d}\rfloor\sum_{i|d}F(i)\mu(\frac{d}{i})
\end{align*}\]

现在只需求出\(\sum_{i|d}F(i)\mu(\frac{d}{i})\)关于d的前缀和就好了。

和上道题一样,枚举\(i\),暴力用它的\(F(i)\)更新它的倍数\(d\)们的\(\sum_{i|d}F(i)\mu(\frac{d}{i})\),复杂度\(O(n\log n)\)。

现在我们还有一个问题没有解决,那就是\(F(i) \le a\)的限制。

如果只有一次询问,这很简单——大于\(a\)的\(F(i)\)都等于0就好了。

现在有好多询问,这也不难——只需离线读入询问,将询问按照\(a\)排序,将所有\(F(i)\)也排序,然后处理每个询问前,把小于等于\(a\)的\(F(i)\)加入树状数组即可。

BZOJ 3529 完整代码

OI中的莫比乌斯反演的更多相关文章

  1. 莫比乌斯反演&各种筛法

    不学莫反,不学狄卷,就不能叫学过数论 事实上大概也不是没学过吧,其实上赛季头一个月我就在学这东西,然鹅当时感觉没学透,连杜教筛复杂度都不会证明,所以现在只好重新来学一遍了(/wq 真·实现了水平的负增 ...

  2. 从 [P4240 毒瘤之神的考验] 谈 OI 中的美学

    感觉这题真的特别有意思,涉及了 OI 中很多非常有意思.非常美的手法,比如--平衡两部分的时间复杂度.\(n \ln n\) 的那个 Trick等等,真的一种暴力的美学. 题目大意: 多组询问,求 \ ...

  3. BZOJ 2154: Crash的数字表格 [莫比乌斯反演]

    2154: Crash的数字表格 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 2924  Solved: 1091[Submit][Status][ ...

  4. 【BZOJ-2440】完全平方数 容斥原理 + 线性筛莫比乌斯反演函数 + 二分判定

    2440: [中山市选2011]完全平方数 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2371  Solved: 1143[Submit][Sta ...

  5. CSU 1325 莫比乌斯反演

    题目大意: 一.有多少个有序数对(x,y)满足1<=x<=A,1<=y<=B,并且gcd(x,y)为p的一个约数: 二.有多少个有序数对(x,y)满足1<=x<=A ...

  6. nyoj CO-PRIME 莫比乌斯反演

    CO-PRIME 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 This problem is so easy! Can you solve it? You are ...

  7. bzoj3529(莫比乌斯反演+离线+树状数组)

    在你以为理解mobus的时候,苦苦想通过化简公式来降低复杂度时,这题又打了我一巴掌. 看来我并没有理解到acmicpc比赛的宗旨啊. 这么多次查询可以考虑离线操作,使用树状数组单点更新. /***** ...

  8. bzoj2154(莫比乌斯反演)

    又是一道经典题. 1.学习了下O(n) 的做法. // // main.cpp // bzoj2154 // // Created by New_Life on 16/7/7. // Copyrigh ...

  9. UVa 11014 (莫比乌斯反演) Make a Crystal

    这个题是根据某个二维平面的题改编过来的. 首先把问题转化一下, 就是你站在原点(0, 0, 0)能看到多少格点. 答案分为三个部分: 八个象限里的格点,即 gcd(x, y, z) = 1,且xyz均 ...

随机推荐

  1. win7中mysql安装

    最近需要用到MySQL,从官网上下载了一个安装文件,但是安装时一直弹出如下提示信息: Configuration of MySQL Server 5.7 is taking longer than e ...

  2. android so壳入口浅析

    本文转自http://www.9hao.info/pages/2014/08/android-soke-ru-kou-q 前言   开年来开始接触一些加固样本,基本都对了so进行了处理,拖入ida一看 ...

  3. Luogu P1484 种树

    这道题目还是比较简单的 首先题目的意思就让我们很轻易地想到DP 我们设f[i][j]表示前i个坑中种j棵树的最大利益,则有: f[i][j]=max(f[i-1][j],f[i-2][j-1]+a[i ...

  4. 微信小程序 Echarts 异步数据更新

    微信小程序 Echarts 异步数据更新的练习,被坑了很多次,特作记录. 作者:罗兵 地址:https://www.cnblogs.com/hhh5460/p/9989805.html 0.效果图   ...

  5. Scala学习(一)练习

    Scala基础学习&l练习 1. 在Scala REPL中键人3.,然后按Tab键.有哪些方法可以被应用 在Scala REPL中需要按3. 然后按Tab才会提示. 直接按3加Tab是没有提示 ...

  6. Codeforces 734E Anton and Tree(缩点+树的直径)

    题目链接: Anton and Tree 题意:给出一棵树由0和1构成,一次操作可以将树上一块相同的数字转换为另一个(0->1 , 1->0),求最少几次操作可以把这棵数转化为只有一个数字 ...

  7. ASYNC_IO_COMPLETION

    项目组有一个数据库备份的Job运行异常,该Job将备份数据存储到remote server上,平时5个小时就能完成的备份操作,现在运行19个小时还没有完成,backup命令的Wait type是 AS ...

  8. Jmeter(二十二)_jenkins配置gitlab插件与ant插件

    Docker部署接口自动化持续集成环境第四步,代码上传到远程仓库! 接上文:脚本上传Gitlab 服务器中的Jenkins通过Gitlab插件读取远程Git远程仓库中的代码,然后通过ant插件进行构建 ...

  9. Js_特效

    事件源对象 event.srcElement.tagName event.srcElement.type 捕获释放 event.srcElement.setCapture();  event.srcE ...

  10. CSAPP lab2 二进制拆弹 binary bombs phase_3

    给出对应于7个阶段的7篇博客 phase_1  https://www.cnblogs.com/wkfvawl/p/10632044.htmlphase_2  https://www.cnblogs. ...