莫比乌斯反演与数论函数

command_block

2018-07-20 09:01:35

Personal

本博客的第一篇博文哦!纪念。 #### ---- 莫比乌斯反演,本质是利用莫比乌斯函数与其他函数间卷积关系,对函数做一系列简化,从而更高效的解决问题。 #### ---- 数论函数,更广阔的天地,因为$\mu∈\text{数论函数}$ # 0.写在前面 这里面式子可能比较多,大家多看看证明,尤其是关键证明以及题目推导过程,**硬记下的结论越少,越不容易忘记**。 (看不清式子可以放大网页) 由于写的时候匆忙,公式可能有错误,请私信或者在下方评论。 每个新东西提出后都会做题或者证明,权当熟悉。 ~~不是一个下午就能看懂的,千万不要直接弃疗~~ - 给大家简要介绍一下符号的意思。 有时候以$(a,b)$简写$gcd(a,b)$。 $\lfloor a\rfloor$表示下取整,比如$\lfloor 2.33\rfloor=2$ $[???]$表示 : 如果$???$为真,则值为1,否则为0.(就像if里面的东西) 比如 $[(8,6)>2]=0;\ [233=233]=1$ $a|b$表示$a$是$b$的因数,注意,前面是后面的因数。 比如 $[2|4]=1;\ [2|3]=0$ $\sum$称为**和式**,意思是对……求和。 比如说$\sum\limits_{i}[1\leq i\leq n]i$,表示枚举变量 $i$,对 $[1\leq i\leq n]i$ 求和。 等价于: ```cpp int ans=0; for (int i=1;i<=n;i++) ans+=i; ``` 我们常把上界写在上面,下界写在下面,如$\sum\limits_{i=1}^ni=1+2+3+...+n$ 有$\sum\limits_{d|6}d=1+2+3+6$ (枚举$6$的因数) # 1.狄利克雷卷积与数论函数 ——介绍了狄利克雷卷积,数论函数(积性函数)的综合 $\color{blue}\text{定义:}$ 数论函数,就是**值域为整数**(陪域为复数,但这不重要)的函数。 也就是说下面出现的数没有特殊说明的话,**都是整数**。 两个**数论函数**的**狄利克雷卷积**是一个**新函数**。 比如$f(n),g(n)$两个函数的狄利克雷卷积写作$\Large{f*g}$ (相当于函数名称)。 什么意思呢? $\color{blue}\text{定义:}$ $\large{(f*g)(n)=\sum\limits_{d|n}f(d)g(n/d)}$ 换句话说就是$\large{(f*g)(n)=\sum\limits_{x*y=n}f(x)g(y)}$ (不过一般不这样写,因为不方便化式子。) 比如说计算$(f*g)(10)$ 可得$f(1)g(10)+f(2)g(5)+f(5)g(2)+f(10)g(1)$ (对于某个新东西,能做到的话,理解的最好方式就是手动模拟) 狄利克雷卷积满足以下运算规律(显而易见,不证): 交换律——$f*g=g*f$; 结合律——$(f*g)*h=f*(g*h)$; (狄利克雷卷积是一个对称的结构) 下面的推导都基于狄利克雷卷积,有必要好好理解。 介绍几个简单的数论函数,让你有个基本概念。 $I(n)$ 无论$n$是啥,它永远等于1,所以叫做~~废柴~~**恒等函数** $ϵ(n)$(也作$e(n)$) 当n=1时,函数值为1,否则为0。被称作**元函数**因为它是卷积的单位元($ϵ*f=f$)。**(Important)** $id(n)=n$ 被称作**单位函数** 附:$id^x(n)=n^x$ 被称作**幂函数**($id(n)$是$id^x(n)$的特殊情况) $e(n),I(n),id(n)$是完全积性函数。 $\color{blue}\text{定义:}$**完全积性函数**: 对于**任意**的整数a和b有$I(ab)=I(a)I(b)$ 附上两个后面会讲的稍微复杂的例子: $\varphi(n)$ 小于n的整数中,与n**互质**的数的**个数**,称作**欧拉函数**(`$\varphi(n)$`)。 $\mu(n)$ 称作**莫比乌斯函数**(`$\mu(n)$`)。 $φ(n)$和$\mu(n)$函数是积性函数(我们后面会证明)。 $\color{blue}\text{定义:}$**积性函数**: 对于一个函数$F$ , 如果$(a,b)=1$时有$F(ab)=F(a)F(b)$,则该函数是积性函数。 积性函数有许多优良性质哦,这些重要的性质我们后面会讲。 很明显,**完全积性函数∈积性函数**。 下面是一些性质: - 对于一个积性函数$F$,有$F(1)=1$ $\color{blue}\text{证明:}$ 根据$F(1)=F(1)F(1)$(定义)可得$F(1)=1$。 - 对于函数$F$,积性$→F(x)=F(p_1^{k_1})F(p_2^{k_2})...F(p_m^{k_m})$ 这里的$p_1...p_m$是指$x$的$m$个**素**因子,也就是把$x$分解的结果。 $k_1...k_m$则是$p_1...p_m$对应的次数。 (比方说1800的分解结果就是$2^3*3^2*5^2$) $\color{blue}\text{证明:}$ 因为$p_1^{k_1},p_2^{k_2},...,p_m^{k_m}$都互质,根据积性易证。 用处:形如$F(prime^k)$的函数值是比较好分析的,我们在利用这个性质来分析一般的情况,后面你们会见到例子。 - 两个积性函数的卷积还是积性函数。 (初学者可以先跳过证明) 设两个积性函数$F_1(x),F_2(x)$。 它们的狄利克雷卷积是$G(n)=\sum\limits_{d|n}F_1(d)F_2(n/d)$ $\color{blue}\text{证明:}$设两数$a,b$互质。 $G(a)G(b)$ $=\sum\limits_{d|a}F_1(d)F_2(a/d)*\sum\limits_{t|b}F_1(t)F_2(b/t)$ $=\sum\limits_{d|a}\sum\limits_{t|b}F_1(d)F_2(a/d)F_1(t)F_2(b/t)$ 把$\sum$合并(根据约数集合的合并),由于$a$与$b$互质,所以$t$与$d$互质。 (根据积性可以把$F_1(d)F_1(t)$化为$F_1(dt)$,$F_2$类似) $=\sum\limits_{dt|ab}F_1(dt)F_2(ab/dt)$ $=G(ab)$,得证. - 积性函数的逆也是积性函数 (初学者可以先跳过证明) 来介绍一下函数在狄利克雷卷积意义下的**逆**。 $\color{blue}\text{定义:}$满足$e=g*f$时,$g$和$f$互逆。 (类比同余逆元理解) 附:函数的逆可以通过某种方式构造出来:[构造方法](https://www.luogu.org/paste/64fn78k9)(~~然并卵~~) $\color{blue}\text{证明:}$ 考虑**数学归纳法**(跟构造方法有点像) 设$e=G*F$,且$F$是积性函数。 我们要证明对于任意的$(a,b)=1$的$a,b$,都满足$G(ab)=G(a)G(b)$ 因为$e=\sum\limits_{d|n}F(d)G(n/d)$ - 1) a或b为1 当$a=b=1$时,$e(1)=1=F(1)G(1)$ 由于积性,根据上文$F(1)=1$,得$G(1)=1$ 所以当$a$或$b=1$时,结论显然成立。 - 2) ab>1 我们考虑已证明了所有的$a'<a;\ b'<b$时,结论成立。 $G(ab)=\sum\limits_{d|ab}F(d)G(ab/d)-\sum\limits_{d|ab,d≠1}F(d)G(ab/d)$ 由$e=G*F$,得$\sum\limits_{d|ab}F(d)G(ab/d)=e(ab)$,由于$ab>1$所以$e(ab)=0$。 $=-\sum\limits_{d|ab,d≠1}F(d)G(ab/d)$ $=-\sum\limits_{i|a,j|b,ij≠1}F(ij)G(ab/ij)$ 根据所有的$a'<a;\ b'<b$时,积性成立得 $=-\sum\limits_{i|a,j|b,ij≠1}F(i)G(j)F(a/i)G(b/j)$ $=-\sum\limits_{i|a,j|b,ij≠1}F(i)G(a/i)F(j)G(b/j)$ 下面**拆分求和号**(乘法分配律),这一步有点难。 $=-\sum\limits_{i|a}F(i)G(a/i)\sum\limits_{j|b,ij≠1}F(j)G(b/j)$ 要求$ij≠1$,即排除$i=j=1$的情况。 $=F(1)F(1)G(a)G(b)-\sum\limits_{i|a}F(i)G(a/i)\sum\limits_{j|b}F(j)G(b/j)$ 由$e=G*F$,得$\sum\limits_{i|a}F(i)G(a/i)\sum\limits_{j|b}F(j)G(b/j)=e(a)e(b)=0$得 $=F(1)F(1)G(a)G(b)$ 由于积性,根据上文$F(1)=1$,得 $=G(a)G(b)$,得证. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ------------ # 2.莫反公式的推导: ——推导了$\mu$函数,莫比乌斯反演定理 有两个单变量函数 **F** 与 **f** 。 设函数 **F** 与 **f** 有如下关系: $F(n)=\sum\limits_{d|n}f(d)$ 理解了上述狄利克雷卷积的定义后,不难发现。 $F(n)=\sum\limits_{d|n}(1*f(d))$(~~废话~~) $F=I*f$ (**F函数是元函数和f函数的卷积**) 现在如果$f$函数易求,那我们可以按照上式算出$F$。 问题在于,如果即$F$函数易求,如何求出$f$? $F=I*f$,两边同时乘以$I^{-1}$得 $f=I^{-1}*F$ 我们只要想办法求出$I^{-1}$就好了。 大佬Möbius把$I^{-1}$命名为$\mu$ 问题在于这个函数里面是什么呢? **$\mu$是个积性函数**,因为积性函数的逆还是积性函数。 这里有个小技巧,研究一个积性函数,**先研究其在质数的幂时的表现**。 比如说$\mu(p^k)$(p是质数)。 **k=0时**,显然有$\mu(1)=1$ **k=1时**,由于$\sum\limits_{d|p}I(d)\mu(p/d)=e(p)=0$ 注意到p为素数,得到$I(p)\mu(1)+I(1)\mu(p)=e(p)=0$ 因为$\mu(1)=1$得$1+\mu(p)=0$,即$\large{\mu(p)=-1}$ **k>1时**,由于$\sum\limits_{d|p^k}I(d)\mu(p^k/d)=e(p^k)=0$ 注意到p为素数,得到$I(p^k)\mu(1)+I(p^{k-1})\mu(p)+...+I(1)\mu(p^k)=e(p^k)=0$ 所有的$I$都为1,得到$\mu(1)+\mu(p)+\mu(p^2)...+\mu(p^k)=0$ 代入$\mu(1)=1,\mu(p)=-1$得到$\mu(p^2)...+\mu(p^k)=0$ 考虑上式k=2的情况,得到$\mu(p^2)=0$ 考虑上式k=3的情况,得到$mu(p^2)+mu(p^3)=0$也就是$mu(p^3)=0$ ……,得到k=任意更大的数时$mu(p^k)=0$ 利用数学归纳法,证明了k>1时,$\mu(p^k)=0$。 大家缓口气哦,$\mu$函数的终极定义马上就证明出来了。 由于上文积性函数性质2: $\mu(n=p_1^{k_1}p_2^{k_2}...p_m^{k_m})=\mu(p_1^{k_1})\mu(p_2^{k_2})...\mu(p_m^{k_m})$ 因为k>1时,$\mu(p^k)=0$ 可以想象到当某一个$k>1$时,$\mu(n)=0$ 不然的话所有的k=1。 可以想象到$\mu(n=p_1p_2...p_m)=(-1)^{m}$ **mu** 函数的$\color{blue}\text{定义}$浮出水面。 ![](https://cdn.luogu.com.cn/upload/pic/48569.png) 现在来介绍莫比乌斯函数是怎么用来反演的。 - **反演公式:** - **嵌入式**莫比乌斯反演: 由$\mu*I=e$得$\sum\limits_{d|n}\mu(d)=[n=1]$ 注意到$[n|m][n/m=1]=[n=m]$ 则有$[n|m]\sum\limits_{d|(n/m)}\mu(d)=[n=m]$ 初学者可以只掌握这一种。 - **约数**的莫比乌斯反演: 若:$\large{F(n)=∑\limits_{d|n}f(d)}$ 则:$\large{f(n)=∑\limits_{d|n}μ(d)F(n/d)}$ 又作$f(n)=∑\limits_{d|n}μ(n/d)F(d)$(和上面那个式子等价) 根据$\mu=I^{-1}$有$f*I=F\rightarrow f=F*\mu$。 如果你们喜欢和式的话:[证明2](https://www.luogu.org/paste/8znlp82b) - **倍数**的莫比乌斯反演: 若:$\large{F(n)=∑\limits_{n|d}f(d)}$ 则:$\large{f(n)=∑\limits_{n|d}μ(d/n)F(d)}$ (这个比较特殊,并不是狄利克雷卷积的形式) 又作$F(n)=\sum\limits_{k}^∞f(kn)$与$f(n)=\sum\limits_{k}^∞\mu(k)F(kn)$ $\color{blue}\text{证明:}$ $∑\limits_{n|d}μ(n/d)F(d)$ 将$F(n)$的定义代入。 $=∑\limits_{n|d}μ(n/d)\sum\limits_{d|t}f(t)$ $=∑\limits_{k}^{∞}μ(k)\sum\limits_{nk|t}f(t)$ 第一个求和号对k没有限制,我们**交换求和号**,考虑枚举t,看有什么对应的k: $=∑\limits_{t}f(t)\sum\limits_{nk|t}\mu(k)=∑\limits_{t}f(t)\sum\limits_{k|(t/n),n|t}\mu(k)$ 根据嵌入式反演能得到$\sum\limits_{k|(t/n),n|t}\mu(k)=[t=n]$ $=∑\limits_{t}f(t)[t=n] =f(n)$,证毕。 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ------------ # 3.知识储备: - **分解质因数**求法,单个mu(n) 直接按照定义,分解因数暴力求。 ```cpp 代码被和谐 //Time:O(sqrt(n)) ``` - **线性筛法**,mu(1~n) (正宗) 利用$\mu$函数的积性性质。 想深入学习线性筛法的看[这里](https://www.cnblogs.com/Paul-Guderian/p/7723031.html)。 ```cpp #include<iostream> #include<cstring> #define MaxNum 10000100 using namespace std; bool e[MaxNum]; int p[MaxNum],tn,mu[MaxNum],n; void Mobius() { e[1]=1;mu[1]=1; for (int i=2;i<=n;i++){ if (!e[i]){p[++tn]=i;mu[i]=-1;} for (int j=1;j<=tn;j++){ if (p[j]*i>n)break; mu[p[j]*i]=i%p[j]==0 ? 0 : -mu[i]; e[p[j]*i]=1; if (i%p[j]==0)break; } } } int main() { cin>>n; Mobius(); for(int i=1;i<=n;++i) printf("%d: %d\n",i,mu[i]); return 0; }//Time:O(n) ``` -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ------------ # 4.第一道题:整除分块 (除了特殊说明,除法均为整除) 讲了那么多,那么问题来了:我们问什么要学莫比乌斯反演?这有什么用呢? 来看一道**题目**。 让你求$\large{\sum\limits_{i=1}^{n}\sum\limits_{j=1}^m[gcd(i,j)=1]}$,也就是互质数对数。($m\leq n$) 大力两重循环+欧几里得$O(n^2logn)$? 悄悄告诉你,正解$O(\sqrt{n})$! $ANS=\sum\limits_{i=1}^{n}\sum\limits_{j=1}^m[(i,j)=1]$。 用**嵌入式反演**替换 : $[(i,j)=1]=\sum\limits_{d|(i,j)}\mu(d)$ - $\color{blue}\text{技巧:}$数对$(i,j)$满足$[d|gcd(i,j)]$的充要条件是$d|i$且$d|j$。 即$[d|(i,j)]=[d|i][d|j]$, 人话就是 : 即是$i$的约数又是$j$的约数的数是$i,j$的公约数。 则有$[(i,j)=1]=\sum\limits_{d|i,d|j}\mu(d)$,这比较重要。 $ANS=\sum\limits_{i=1}^{n}\sum\limits_{j=1}^m\sum\limits_{d|i,d|j}\mu(d)$ $\color{blue}\text{技巧:}$ 我们考虑**交换求和顺序**,分别查看每个变量的限制。 $d$最先枚举,考虑其范围,显然在$[1,n]$以内。 $i$必须要满足$d|i$,且在$[1,n]$以内。 $j$必须要满足$d|j$,且在$[1,n]$以内。 $ANS=\sum\limits_{d=1}^n\mu(d)\sum\limits_{d|i}^{n}\sum\limits_{d|j}^m1$ 观察后面的$\sum\limits_{d|i}^{n}\sum\limits_{d|j}^m1=(\sum\limits_{d|i}^{n}1)(\sum\limits_{d|j}^m1)$ 而$\sum\limits_{d|i}^{n}1$相当于$n$以内$d$的倍数的个数,显然为$\lfloor n/d\rfloor$ 就得到$ANS=\sum\limits_{d=1}^n\mu(d)\lfloor n/d\rfloor\lfloor m/d\rfloor$ 这样子就可以$O(n)$计算了。 $\color{blue}\text{技巧:}$怎么做到$O(\sqrt{n})$呢?需要一个叫做**整除分块**的技巧。 [整除分块入门小记](https://www.luogu.org/blog/command-block/zheng-chu-fen-kuai-ru-men-xiao-ji) 好的,下面我们默认你会整除分块了。 回顾上面的问题,我们已经变形到了$ANS=∑\limits_{d=1}^{min(n,m)}μ(d)\lfloor n/d\rfloor \lfloor m/d\rfloor$ 看到和式后面的$\lfloor n/d\rfloor \lfloor m/d\rfloor$,是可以整除分块的。 问题是还乘了个$\mu(d)$,根据套路弄个前缀和搞定。 (如果这句听不懂,把入门小记再看一遍) 即$\mu([l,r])$的和乘上$\lfloor n/d\rfloor \lfloor m/d\rfloor$。 Code: ```cpp #include<iostream> #define MaxNum 100100 using namespace std; int p[MaxNum/8],tn,mu[MaxNum],n,m; bool e[MaxNum]; long long calc(int n,int m) { long long ans=0; for (int l=1,r=0;l<=min(n,m);l=r+1){ r=min(n/(n/l),m/(m/l));// 分段 ans+=1ll*(mu[r]-mu[l-1])*(n/l)*(m/l); }return ans; } int main() { e[1]=1;mu[1]=1; for (int i=2;i<=MaxNum;i++){ if (!e[i]){p[++tn]=i;mu[i]=-1;} for (int j=1;j<=tn;j++){ if (p[j]*i>MaxNum)break; mu[p[j]*i]=i%p[j]==0 ? 0 : -mu[i]; e[p[j]*i]=1; if (i%p[j]==0)break; } }for (int i=2;i<=MaxNum;i++)mu[i]+=mu[i-1]; //筛法弄出mu前缀和,参看前文 cin>>n>>m; cout<<calc(n,m)<<endl; return 0; } ``` ~~后面你会看到,莫比乌斯反演不分块复杂度就是一堆垃圾。~~ ~~分块是肯定要分块的,这辈子都要分块的~~ 恭喜你,已经在莫比乌斯反演的路上迈出了第一步! 附送可以**利用**上述代码AC的练手题[Link1](https://www.luogu.org/problemnew/show/P3455)+[Link2](https://www.luogu.org/problemnew/show/P2158) -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ------------ ## 5.技巧进阶:莫反常用结论以及练习 莫比乌斯反演是极具技巧性的。 主要的思维难度就建立在**反演**和**分块**两部分。 看题吧。 ### 第一题[P2568 GCD](https://www.luogu.org/problemnew/show/P2568) 求$\sum\limits_{i=1}^n\sum\limits_{j=1}^n[(i,j)=prime]$ 在上一题中,我们解决了求$\sum\limits_{i=1}^{n}\sum\limits_{j=1}^n[(i,j)=1]$的问题,而且我们已经能够做到$O(\sqrt{n})$求解了。 我们尝试求$\sum\limits_{i=1}^n\sum\limits_{j=1}^n[(i,j)=d]$ - 注意到,$[(i,j)=d]$蕴含$d|i$且$d|j$. $=\sum\limits_{d|i}^n\sum\limits_{d|j}^n[(i,j)=d]$ - $\color{blue}\text{技巧:}$ 既然$i,j$都是$d$的倍数,我们不妨把$i,j$都除以$d$ 此时,后面原有的$i$需要还原成$id$,原有的$j$要还原成$jd$ $=\sum\limits_{i=1}^{n/d}\sum\limits_{j=1}^{n/d}[(id,jd)=d]$ - $[(id,jd)=d]=[d(i,j)=d]=[(i,j)=1]$ $=\sum\limits_{i=1}^{n/d}\sum\limits_{j=1}^{n/d}[(i,j)=1]$,又回到了我们熟悉的问题! 求解的复杂度是$O(\sqrt{n/d})$ 对于每个素数求解的复杂度是$O\Big(\sum\limits_{p\in Prime}^{n}{\sqrt{n/p}}\Big)$ $=\sqrt{n}\sum\limits_{p\in Prime}^{n}{\sqrt{1/p}}$ 将素数视为平均分布,可估计额$\frac{1}{\log n}\sum\limits_{p=1}^{n}\sqrt{1/p}$ 接下来需要一点微积分知识 : $\sum\limits_{p=1}^{n}\sqrt{1/p}=\sqrt{n}$ 总的复杂度就是$O(n/\log n)$ 对于不会计算复杂度的同学,可以暴力统计一下式子的值,看看能不能过就好了。 **Code:** ```cpp #include<iostream> #include<cstdio> #define MaxNum 10000010 using namespace std; long long p[MaxNum/10],tn,mu[MaxNum+50],anss,ttn,n,aaa; bool e[MaxNum+50]; void getmu() { e[1]=1;mu[1]=1; for (long long i=2;i<=MaxNum;i++){ if (!e[i])mu[p[++tn]=i]=-1; for (int j=1;j<=tn&&i*p[j]<MaxNum;j++){ e[i*p[j]]=1; mu[i*p[j]]=i%p[j]? -mu[i] : 0; if (!i%p[j])break; } } } //sum(1,N/n)sum(1,N/n)[gcd(i,j)==1] long long gg(int n){ long long ans=0; for (int l=1,r=0;l<=n;l=r+1){ r=n/(n/l); // 分段 ans+=1ll*(mu[r]-mu[l-1])*(n/l)*(n/l); }return ans; } int main() { getmu(); for (int i=2;i<=MaxNum;i++)mu[i]+=mu[i-1]; cin>>n; long long ans=0; for (int i=2;i<=n;i++) if(!e[i])ans+=gg(n/i); cout<<ans; return 0; } ``` [P2257 YY的GCD](https://www.luogu.org/problemnew/show/P2257) 貌似和上一题相同呢?发现$T<=10000$。 上一题的$O(n/\log n)$还要乘上数据组数,肯定是跑不过去的。 我们将上面的最终式子整理: $\sum\limits_{p∈Prime}^{n}f(p)=\sum\limits_{p∈Prime}^{n}∑\limits_{d=1}^{m/p}μ(d)\lfloor n/dp\rfloor\lfloor m/dp\rfloor$ $\color{blue}\text{技巧:}$ 现在又有个蛇皮操作叫**改变枚举变量** 说起$dp$,我就想起……开机……弘扬中华文化。 还是把$dp$换一下吧,就令$dp=k$**我们枚举k**。容易发现$dp≤min(n,m)$ 明显的,$d$和$p$都是k的约数,我们再枚举$p$,得到$d=k/p$。(把枚举k的和式放在最前面) $\sum\limits_{k=1}^{min(n,m)}∑\limits_{p∈prime,p|k}μ(k/p)\lfloor n/k\rfloor\lfloor m/k\rfloor$ 我们发现只有$μ(k/p)$一项和$p$有关,所以我们可以把$μ(k/p)$连着$∑\limits_{p∈prime,p|k}$一起放到最后面。 得到$\sum\limits_{k=1}^{min(n,m)}\lfloor n/k\rfloor\lfloor m/k\rfloor∑\limits_{p∈prime,p|k}μ(k/p)$ 前面的$\sum\limits_{k=1}^{min(n,m)}\lfloor n/k\rfloor\lfloor m/k\rfloor$就可以**整除分块**了。 至于后面的$∑\limits_{p∈prime,p|k}μ(k/p)$还是套路,维护一个有关于$k$的前缀和。 怎么弄出前缀和,就是考验数论~~口胡~~基本功的时候啦,这里也介绍一下。 设$g(k)=∑\limits_{p∈prime,p|k}μ(k/p)$ 先线筛出$\mu$,然后枚举$p$,对于 $p|k$ 的$k$将$g[k]+=\mu(k/p)$。(贡献模式,好好理解) 这样的话对于一个素数$p$,复杂度为$O(n/p)$ 复杂度和埃氏筛相同,为$O(n\log\log n)$ 每个询问$O(\sqrt{n})$,总的复杂度$O(t\sqrt{n}+n\log\log n)$ 亮出代码: ```cpp #include<algorithm> #include<cstdio> using namespace std; int t,n,m,tn,p[1000500],mu[10000500],g[10000500]; bool e[10000500]; void getmu() { e[1]=1;mu[1]=1; for (int i=2;i<=10000100;i++){ if (!e[i]){ p[++tn]=i; mu[i]=-1; }for (int j=1;j<=tn;j++){ if (1ll*i*p[j]>10000100)break; e[i*p[j]]=1; mu[i*p[j]]=i%p[j] ? -mu[i] : 0; if (!i%p[j])break; } }//线筛出mu } long long calc(int n,int m) { long long ans=0; int l=1,r; for (;l<=min(n,m);l=r+1){ r=min(n/(n/l),m/(m/l));//整除分块 ans+=1ll*(n/l)*(m/l)*(g[r]-g[l-1]); }return ans; } int main() { scanf("%d",&t); getmu(); for (int i=1;i<=tn;i++) for (int j=p[i];j<=10000100;j+=p[i]) g[j]+=mu[j/p[i]]; for (int i=2;i<=10000100;i++)g[i]+=g[i-1]; //预处理前缀和 while(t--){ scanf("%d%d",&n,&m); printf("%lld\n",calc(n,m)); }return 0;} ``` $\color{blue}\text{附加题:}$ [P5221 Product](https://www.luogu.org/problemnew/show/P5221) **&** [My Sol](https://www.luogu.org/blog/command-block/solution-p5221) -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ------------ ## 6.探索新知:其他数论函数 想必经过上面的学习,大家对$\mu$已经有了一定的了解,运用反演定理也更熟练了些,那么我们一起向**数论函数**这个广阔的天地进发吧! $\color{blue}\text{定义:}$**常用数论函数表:** | 函数名称 | 符号 | 定义 | 积性 | 卷积 | -------: | -------: | -------: | -------: | -------: | | 恒等函数 \|| $I(n)$ \|| 永远等于1 \|| 完全积性函数 \|| | | 元函数 \|| $ϵ(n)$(也作$e(n)$) \|| 当n为1时,函数值为1,否则为0 \|| 完全积性函数 \|| | | 单位函数 \|| $id(n)$ \|| 函数值为n \|| 完全积性函数 \|| | | 幂函数 \|| $id^x(n)$ \|| 函数值为$n^x$ \|| 完全积性函数 \|| | | 莫比乌斯函数 \|| $\mu(n)$`\mu` \|| $\mu*I=e$ \|| 积性函数 \|| $\mu*I=e$ | | 欧拉函数\|| $\varphi(n)$`\varphi` \|| 小于等于n的数中,与n互质的数的个数 \|| 积性函数 \|| $\varphi*I=id$ | | 约数个数函数 \|| $d(n)$(也作$σ_0(n)$) \|| n的约数个数 \|| 积性函数 \|| $d=I*I$ | | 约数和函数 \|| $σ(n)$ \|| n的约数和 \|| 积性函数 \|| $σ=id*I$ | | | 除数函数 \|| $σ^k(n)$ \|| n的约数k次方和 \|| 积性函数 \|| $σ^k=id^k*I$ | ### 1) 欧拉函数 $\color{blue}\text{定义:}$欧拉函数,$\varphi(n)$,其值为“小于等于n的数中,与n互质的数的个数”。 这个函数是可以辅助解(理解)很多的数论题的,它的地位差不多和$\mu$一样重要。 而且,$\varphi$和$\mu$之间有某些神秘联系,这一点要等我们先讲完狄利克雷卷积的一些玩法先。 先讲解这个$\varphi$的**基本操作**: $\color{blue}\text{性质:}$首先$\varphi$是**积性函数**。 $\color{blue}\text{证明:}$因为$\varphi(n)=\sum\limits_{i=1}^n[(n,i)=1]$ 设$(n,m)=1$, 得$\varphi(n)\varphi(m)=\sum\limits_{i=1}^n[(n,i)=1]\sum\limits_{j=1}^m[(m,j)=1]$ 即$\sum\limits_{i=1}^n\sum\limits_{j=1}^m[(m,j)=1\ {\bf and}\ (n,i)=1]$ 由于互质,$[(m,j)=1\ {\bf and}\ (n,i)=1]$**等价于**$[(nm,im+jn)=1]$。 因为$\gcd\Big((im+jn)\bmod n,n\Big)=\gcd(im,n)=1$,且$\gcd\Big((im+jn)\bmod m,m\Big)=\gcd(jn,m)=1$ 我们还要证明所有的$(in+jm)\bmod {nm}$**恰好**组成$[1...nm]$的集合。 首先,这些二元组的大小为$nm$,和目标集合大小相同,我们只需要证明这些元素两两不同即可。 **前置芝士** : $ca=cb\pmod p$且$(c,p)=1$,则有$a=b$. (可见[同余系基本定理1](https://www.luogu.com.cn/blog/command-block/tong-yu-xi1)) - 采用反证法,假如有$am+bn=cm+dn\pmod {nm}$ 我们将两边对$m$取模得到$bn=dn\pmod {m}$,由引理得$b=d$,同理有$a=c$,矛盾。 那么$(in+jm)\bmod {nm}$的集合与$[1...nm]$的集合一一对应,且贡献模式相同。 于是上式等价于$\sum\limits_{i=1}^{nm}[(nm,i)=1]=\varphi(nm)$ 如何求积性函数的前n个值呢? **线性筛!** 对于线性筛,我们要解决$\varphi(prime^k)$类的函数值。(下面的$p$均为素数) $\color{blue}\text{性质:}$ $\varphi(p^k)=(p-1)p^{(k-1)}$ $\color{blue}\text{证明:}$ $\varphi(p)=p-1$,这是很明显的:小于$p$的数都与$p$互质。 很明显$p^k$以内的数与$p^k$互质的充要条件是:它们没有公因数$p$。 那么把所有含有因数$p$的数去掉,剩下$\dfrac{(p-1)*p^k}{p}=(p-1)p^{(k-1)}$个。 在实用中这个定理有另外一个形式: 如果$p|n$,则$\varphi(np)=\varphi(n)*p$ $\color{blue}\text{证明:}$设$n=p^k*m$,那么$\varphi(n)=\varphi(m)*\varphi(p^k)=\varphi(m)*(p-1)p^{(k-1)}$ 则$np=p^{(k+1)}*m$,那么$\varphi(np)=\varphi(m)*\varphi(p^{(k+1)})=\varphi(m)*(p-1)p^k$ 原命题明显成立。 **Code:** ```cpp bitset<MaxN> e; int p[MaxN/10],tn; long long ans,phi[MaxN]; void getphi() { phi[1]=1; for (int i=2;i<=n;i++){ if (!e[i]){ p[++tn]=i; phi[i]=i-1; }for (int j=1,t;j<=tn&&(t=i*p[j])<=n;j++){ e[t]=1; phi[t]=phi[i]*(i%p[j]?p[j]-1:p[j]); //此处注意 if (i%p[j]==0)break; } } } ``` - 代码里"此处注意": 如果$(i,p)=1$,则$\varphi(ip)=\varphi(i)*\varphi(p)=(p-1)\varphi(i)$ 如果$p|i$,根据上文的定理,$\varphi(ip)=\varphi(i)*p$ - **附:** 有些时候我们需要求出单个的$\varphi(n)$,如果按照定义大力求,至少得$O(n)$次$\gcd$。 我们把$n$分解得$p_1^{k_1}*p_2^{k_2}*...*p_m^{k_m}$ 那么$\varphi(n)=\varphi(p_1^{k_1})*\varphi(p_2^{k_2})*...*\varphi(p_m^{k_m})=\dfrac{(p_1-1)p_1^k}{p_1}*\dfrac{(p_2-1)p_2^k}{p_2}*...\dfrac{(p_m-1)p_m^k}{p_m}$ $=(p_1^kp_2^{k_2}...p_m^{k_m})*\left(\dfrac{p_1-1}{p_1}*\dfrac{p_2-1}{p_2}*...*\dfrac{p_m-1}{p_m}\right)=n\left(\dfrac{p_1-1}{p_1}*\dfrac{p_2-1}{p_2}*...*\dfrac{p_m-1}{p_m}\right)$ $\color{blue}\text{性质:}$ $\varphi(n=p_1^kp_2^{k_2}...p_m^{k_m})=n\left(\dfrac{p_1-1}{p_1}*\dfrac{p_2-1}{p_2}*...*\dfrac{p_m-1}{p_m}\right)$ 根据上式,把$n$质因数分解即可求出$\varphi(n)$,复杂度$O(\sqrt{n})$ **Code:** ```cpp int phi(int n) { int ans=n; for (int i=2;i*i<=n;i++) if (n%i==0){ ans=ans/i*(i-1); //根据上文式子计算 while(n%i==0)n/=i; } if (n>1)ans=ans/n*(n-1); //如果分解不尽,那么肯定还剩一个素数 return ans; } ``` 我们来看看$\varphi$的经典**应用**: [题目](https://www.luogu.org/problemnew/show/P2398) 相信你能直接想到一个莫比乌斯反演的做法: - 设$f(n)$是$\sum\limits_{i=1}^n\sum\limits_{j=1}^n[(i,j)=1]$ 考虑枚举gcd那么答案是$\sum\limits_{d=1}^nd\sum\limits_{i=1}^n\sum\limits_{j=1}^n[(i,j)=d]$ 后面的$\sum\limits_{i=1}^n\sum\limits_{j=1}^n[(i,j)=d]=\sum\limits_{i=1}^{(n/d)}\sum\limits_{j=1}^{(n/d)}[(i,j)=1]=f(n/d)$ 答案化为$\sum\limits_{d=1}^nd*f(n/d)$。 对$f(n)$反演,……即为$∑\limits_{d=1}^{n}μ(d)(n/d)^2$,用整除分块求一次$f$时间复杂度$O(\sqrt{n})$ 按$\sum\limits_{d=1}^nd*f(n/d)$计算即可$O(n\sqrt{n})$。 考虑对$f(n/d)$的$n/d$整除分块,即可$O(n)-O(n^{3/4})$(方法参照上文,证明需用积分)。 其实利用$\varphi$可以**很方便**地解决上述问题,复杂度是$O(n)-O(\sqrt{n})$。 设$f(n)$是$\sum\limits_{i=1}^n\sum\limits_{j=1}^n[(i,j)=1]$ 我们知道$\varphi(n)$的定义是:小于等于n的数中,与n互质的数的个数。 我们把$\varphi(1)+\varphi(2)+...+\varphi(n)$加起来,则可以得到**每个数与自己更小的数互质的次数和**。 即$\sum\limits_{i=1}^n\sum\limits_{j=1}^i[(i,j)=1]=\sum\limits_{i=1}^n\varphi(i)$ 现在,每个数只能统计比自己小的互质产生贡献,也就是,只统计了数对$(x,y)$中$x>=y$的部分。 我们考虑$(x,y)$中$x<=y$的部分贡献,显然和上式相同。 (想像一个邻接矩阵) 乘以$2$就好了,但是由于$(1,1)=1$会多算一次,所以答案减1。 $\color{blue}\text{技巧:}$得到$\sum\limits_{i=1}^n\sum\limits_{j=1}^n[(i,j)=1]=2\left(\sum\limits_{i=1}^n\varphi(i)\right)-1$ 我们设$S(n)=\sum\limits_{i=1}^n\varphi(i)$(前缀和),上式变为$f(n)=2*s(n)-1$ 答案变为$\sum\limits_{d=1}^nd*f(n/d)=\sum\limits_{d=1}^nd*(2*S(n/d)-1)$已经可以做到$O(n)$了,再整除分快一次就可以$O(\sqrt{n})$了。 然后使用线性筛就得到$O(n)-O(\sqrt{n})$的算法了。 **Code:** ```cpp #include<cstdio> #include<bitset> #define MaxN 10000500 using namespace std; int n; bitset<MaxN> e; int p[MaxN/10],tn; long long ans,phi[MaxN]; void getphi() { phi[1]=1; for (int i=2;i<=n;i++){ if (!e[i]){ p[++tn]=i; phi[i]=i-1; }for (int j=1,t;j<=tn&&(t=i*p[j])<=n;j++){ e[t]=1; phi[t]=phi[i]*(i%p[j]?p[j]-1:p[j]); if (i%p[j]==0)break; } } } int main() { scanf("%d",&n); getphi(); for (int i=1;i<=n;i++)phi[i]+=phi[i-1]; for (int i=1;i<=n;i++)ans+=(phi[n/i]*2-1)*i; printf("%lld",ans); } ``` 这个解法相对莫比乌斯反演有什么好处呢? **代码短啊!** 如果多组询问的话,就可以使用数论分块$O(\sqrt{n})$回答啦。 重申经典结论:$\sum\limits_{i=1}^n\sum\limits_{j=1}^n[(i,j)=1]=\left(\sum\limits_{i=1}^n\varphi(i)*2\right)-1$ 既然欧拉函数这么好用,为啥还要反演呢? 求$\sum\limits_{i=1}^n\sum\limits_{j=1}^m(i,j)$? 欧拉函数就没法直接按照定义做了。 这么说太过于人类智慧了,下面,我们考虑使用狄利克雷卷积来系统分析。 ### 2)一些狄利克雷卷积结论: - $id=I*\varphi$ 即$\sum\limits_{d|n}\varphi(d)=n$ 这个东西是比较重要的,相应地,证明也很长。 $\color{blue}\text{证明:}$设$id*\varphi=F$ 我们知道$F$是个积性函数,那么我们只要证明所有的$F(prime^k)=prime^k$成立。 然后根据积性和唯一分解定理,把结论扩展到全体正整数。 $\sum\limits_{d|p^k}\varphi(d)=\varphi(1)+\varphi(p)+\varphi(p^2)+...+\varphi(p^k)$ 根据$\varphi(p^k)=(p-1)p^{(k-1)}$,$\varphi(1)=1$ $=1+(p-1)+(p-1)p+(p-1)p^2...+(p-1)p^{(k-1)}$ $=1+(p-1)(1+p+p^2+...p^{(k-1)})$ $=1+(p-1)\dfrac{p^k-1}{p-1}=p^k$ 证毕。 根据$I^{-1}=\mu$,可得$id=I*\varphi$等价于$\mu*id=\varphi$ 即$\sum\limits_{d|n}\mu(d)(n/d)=\varphi(n)$ 这个结论极其有用,比如说我们求$\sum\limits_{i=1}^n\sum\limits_{j=1}^m(i,j)$ 利用莫比乌斯反演,变形为$\sum\limits_{d=1}^nd*∑\limits_{t=1}^{n/d}μ(t)\lfloor n/dt\rfloor\lfloor m/dt\rfloor$ 设$p=dt$,上式即为 $=\sum\limits_{d=1}^nd*∑\limits_{d|p}^{n}μ(p/d)\lfloor n/p\rfloor\lfloor m/p\rfloor$ 可以交换求和号,得到 $=∑\limits_{p=1}^{n}\sum\limits_{d|p}d*μ(p/d)\lfloor n/p\rfloor\lfloor m/p\rfloor$ 发现中间的$\sum\limits_{d|p}d*μ(p/d)$就是$\mu*id$所以等于$\varphi(p)$ $=∑\limits_{p=1}^{n}\varphi(p)\lfloor n/p\rfloor\lfloor m/p\rfloor$ (这个式子是可以整除分块的) 这样就可以解决上文留下的问题了。 ### 3)除数函数相关 - $d=I*I$ ; $\color{blue}\text{证明:}$ $d(n)=\sum\limits_{d|n}1=\sum\limits_{d|n}I(d)I(n/d)=(I*I)(n)$ - $σ=id*I$ $\color{blue}\text{证明:}$ $d(n)=\sum\limits_{d|n}d=\sum\limits_{d|n}id(d)I(n/d)=(id*I)(n)$ 把$n$分解得到$p_1^{k_1}*p_2^{k_2}*...*p_m^{k_m}$ $d(n)=(k_1+1)(k_2+1)...(k_m+1)$ $\color{blue}\text{证明:}$对于每个素因子可以选0~k个,乘法原理。 $σ(n)=(1+p_1+p_1^2+...+p_1^{k_1})(1+p_2+p_2^2+...+p_2^{k_2})...(1+p_m+p_m^2+...+p_m^{k_m})$ $=(\dfrac{p_1^{(k_1+1)}-1}{p_1-1})(\dfrac{p_2^{(k_2+1)}-1}{p_2-1})...(\dfrac{p_m^{(k_m+1)}-1}{p_m-1})$ $\color{blue}\text{证明:}$对于每个素因子可以选0~k个,拆完括号后刚好得到所有约数。 另外:$\sum\limits_{i=1}^nd(n)=\sum\limits_{i=1}^n\left\lfloor\dfrac{n}{i}\right\rfloor$ $\color{blue}\text{证明:}$考虑$i$在1~n中被作为约数的次数,得$\left\lfloor\dfrac{n}{i}\right\rfloor$次。 [一道题目](https://www.luogu.org/problemnew/show/P3935) ### 4)一些(跳跃性)结论 在做某些毒瘤题的时候有奇效。 - 莫比乌斯函数$\mu(n)$ 有$\mu(ij)=\mu(i)\mu(j)[i\perp j]$ 这个容易,假如$(i,j)$大于1,那么一定会导致出现平方因子,式子的值为0. 否则按照积性分解即可。 - 除数函数$d(n)$ 有$d(ij)=\sum\limits_{x|i}\sum\limits_{y|j}[x\perp y]$ $\color{blue}\text{证明:}$ ~~比较难,只会从右边推到左边。~~ 把$i$分解得到$p_1^{k_1}*p_2^{k_2}*...*p_m^{k_m}$,$j$分解得到$p_1^{k_1'}*p_2^{k_2'}*...*p_m^{k_m'}$ $d(ij)=(k_1+k_1'+1)(k_2+k_2'+1)...(k_m+k_m'+1)$ 显然,每个质因子是独立的,我们考虑$i=p^a;j=p^b$的情况。 $\sum\limits_{x|i}\sum\limits_{y|j}[x\perp y]=\sum\limits_{x'=0}^a\sum\limits_{y'=0}^b[x',y'\text{不同时为正}]$ 大眼观察可得只有 $x'$取$0...a$,且$y'$取0这$a+1$个, $y'$取$0...b$,且$x'$取0这$b+1$个,减去重复算的$(0,0)$,正好是$(a+b+1)$,符合要求。 - 欧拉函数$\varphi(n)$ 有$\varphi(ij)=\dfrac{\varphi(i)\varphi(j)(i,j)}{\varphi((i,j))}$ $\color{blue}\text{证明:}$ 默认$p$指质数。 $\varphi(ij)=ij\prod\limits_{p|ij}\dfrac{p-1}{p}$ 考虑到$[p|ij]=[p|i\ or\ p|j]=[p|i]+[p|j]-[p|(i,j)]$ $=ij\left(\dfrac{\prod\limits_{p|i}\dfrac{p-1}{p}\prod\limits_{p|j}\dfrac{p-1}{p}}{\prod\limits_{p|(i,j)}\dfrac{p-1}{p}}\right)$ $=\dfrac{i\prod\limits_{p|i}\dfrac{p-1}{p}j\prod\limits_{p|j}\dfrac{p-1}{p}(i,j)}{(i,j)\prod\limits_{p|(i,j)}\dfrac{p-1}{p}}$ $=\dfrac{\varphi(i)\varphi(j)(i,j)}{\varphi((i,j))}$