当前位置: 首页 > news >正文

浅谈一类积性函数的前缀和

写在前面

笔者在刷题过程中遇到一些求积性函数前缀和的问题,其中有一类问题需要在低于线性时间复杂度的算法,今天就来浅析一下这类问题的求解方法,当作以后讲课使用的讲义。若之后有了新的研究,再来继续完善这篇文章。
本文会随时更新内容,建议想要转载的朋友只转链接,或者与笔者保持联系,另外爬虫转载必究……

author: skywalkert
original article: http://blog.csdn.net/skywalkert/article/details/50500009
last update time : 2016-06-02


前置技能

积性函数的定义

  1. f(n) 的定义域为正整数域,值域为复数,即 f:Z+C ,则称 f(n) 数论函数
  2. f(n) 为数论函数,且 f(1)=1 ,对于互质的正整数 p,q f(pq)=f(p)f(q) ,则称其为积性函数
  3. f(n) 为积性函数,且对于任意正整数 p,q 都有 f(pq)=f(p)f(q) ,则称其为完全积性函数

积性函数的性质与例子

  1. 常见的积性函数有
    • 除数函数 σk(n)=d|ndk ,表示 n 的约数的 k 次幂和,注意 σk(n) σk(n) 是不同的。
    • 约数个数函数 τ(n)=σ0(n)=d|n1 ,表示 n 的约数个数,一般也写为 d(n)
    • 约数和函数 σ(n)=σ1(n)=d|nd ,表示 n 的约数之和。
    • 欧拉函数 φ(n)=ni=1[(n,i)=1]1 ,表示不大于 n 且与 n 互质的正整数个数,另外 ni=1[(n,i)=1]i=nφ(n)+[n=1]2 ,且对于正整数 n>2 来说 φ(n) 是偶数。
    • 莫比乌斯函数 μ(n) ,在狄利克雷卷积的乘法中与恒等函数互为逆元, μ(1)=1 ,对于无平方因子数 n=ti=1pi μ(n)=(1)t ,对于有平方因子数 n μ(n)=0
    • 元函数 e(n)=[n=1] ,狄利克雷卷积的乘法单位元,完全积性。
    • 恒等函数 I(n)=1 ,完全积性。
    • 单位函数 id(n)=n ,完全积性。
    • 幂函数 idk(n)=nk ,完全积性。
  2. 关于莫比乌斯函数和欧拉函数有两个经典的公式
    • [n=1]=d|nμ(d) ,将 μ(d) 看作是容斥的系数即可证明。
    • n=d|nφ(d) ,将 in(1in) 化为最简分数统计个数即可证明。
  3. f(n) 为积性函数,则对于正整数 n=ti=1pkii f(n)=ti=1f(pkii) ;若 f(n) 为完全积性函数,则对于正整数 n=ti=1pkii f(n)=ti=1f(pi)ki

狄利克雷卷积与莫比乌斯反演

  1. 数论函数 f g 狄利克雷卷积定义为 (fg)(n)=d|nf(d)g(nd) ,狄利克雷卷积满足交换律、结合律,对加法满足分配律,存在单位元函数 e(n)=[n=1] 使得 fe=f=ef ,若 f g 为积性函数则 fg 也为积性函数。
  2. 狄利克雷卷积的一个常用技巧是对于积性函数 f 与恒等函数 I 的卷积的处理,例如 n=ti=1pkii,g(n)=d|nf(d) ,则有 g(n)=ti=1kij=0f(pji)
  3. 莫比乌斯反演也是对于 g(n)=d|nf(d) 的讨论,但是不要求 f 是积性函数,适用于已知 g(n) f(n) 的情况,由于 Iμ=e ,则 gμ=fIμ=fe=f ,即 f(n)=d|ng(d)μ(nd) ,类似地有 g(n)=n|df(d)f(n)=n|dg(d)μ(dn) ,二项式反演也是类似的技巧。有一个例子可以看出欧拉函数和莫比乌斯函数之间的关系,由于 d|nφ(d)=id(n) ,所以 φ(n)=d|nμ(d)nd ,也即 φ(n)n=d|nμ(d)d

正文:黑科技

这种黑科技大概起源于Project Euler这个网站,由xudyh引入中国的OI、ACM界,目前出现了一些OI模拟题、OJ月赛题、ACM赛题是需要这种技巧在低于线性时间的复杂度下解决一类积性函数的前缀和问题。

首先看一个简单的例子,求前 n 个正整数的约数之和,即 ni=1σ(i) ,其中 n1012
显然不能直接做了,但是我们可以推导一番:

i=1nσ(i)=i=1nj=1n[j|i]j=i=1nij=1n[i|j]=i=1nini

in 时, ni 显然只有 O(n) 个取值;当 i>n 时, ni<n 显然也只有 O(n) 个取值;对于固定的 ni i 的取值是一段连续的区间,当 ni>1 时这段区间是 [nni1+1,nni] ,因此可以 O(n) 计算所求。
同样地,求前 n 个正整数的约数个数之和也可以这样计算,留给读者练习。
另外需要说明的是, ni=1nii=ni=1ni(ni+1)2 ,这也是一种常见的表示形式。

现在我们来加大一点难度,求前 n 个正整数的欧拉函数之和,即 ni=1φ(i) ,其中 n1011
目前本文提到的有关欧拉函数的公式只有几个,是否能用它们来帮助化简呢?答案是肯定的,接下来我们就利用 d|nφ(d)=n 来化简这个式子。
这个公式也可以看成是 φ(n)=nd|n,d<nφ(d) ,设 ϕ(n)=ni=1φ(i) ,则有

ϕ(n)=i=1nφ(i)=i=1nid|i,d<iφ(d)=n(n+1)2i=2nd|i,d<iφ(d)=n(n+1)2id=2nd=1nidφ(d)=n(n+1)2i=2nd=1niφ(d)=n(n+1)2i=2nϕ(ni)

那么只要计算出 O(n) ϕ(ni) 的值,就可以计算出 ϕ(n) ,这样的复杂度又如何呢?
假设计算出 ϕ(n) 的复杂度为 T(n) ,则有 T(n)=O(n)+ni=1T(i)+T(ni) 只展开一层就可以了,更深层的复杂度是高阶小量,所以有 T(n)=ni=1O(i)+O(ni)=O(n34)
由于 ϕ(n) 是一个积性函数的前缀和,所以筛法也可以预处理一部分,假设预处理了前 k 个正整数的 ϕ(n) ,且 kn ,则复杂度变为 T(n)=nki=1ni=O(nk) ,当 k=O(n23) 时可以取到较好的复杂度 T(n)=O(n23)
之前利用 φ(n)=nd|n,d<nφ(d) 的地方是怎么想到的呢?不妨来看一下这个
n(n+1)2=i=1ni=i=1nd[d|i]φ(d)=id=1nd=1nidφ(d)=i=1nϕ(ni)

如果能通过狄利克雷卷积构造一个更好计算前缀和的函数,且用于卷积的另一个函数也易计算,则可以简化计算过程。例如上题就是利用了 φI=id 的性质,但一定注意,不是所有的这一类题都只用配个恒等函数 I 就可以轻松完事的,有时需要更细致的观察。

定义梅滕斯函数 M(n)=ni=1μ(i) ,给定正整数 n ,计算 M(n) ,其中 n1011
有了欧拉函数的经验,这次似乎就轻车熟路了吧,使用 [n=1]=d|nμ(d) 来试试?

1=i=1n[i=1]=i=1nd|iμ(d)=i=1nd=1niμ(d)=i=1nM(ni)

因此 M(n)=1ni=2M(ni) ,问题可在 O(n23) 时间复杂度下解决。

看了上面的例子,是不是认为这种做法很naive,很好学啊,再来看一个题吧!
A(n)=ni=1i(n,i),F(n)=ni=1A(i) ,求 F(n) (109+7) 的值,其中 n109
先做一番化简,变成积性函数前缀和的样子:

A(n)=i=1ni(n,i)=i=1nd|n[(n,i)=d]id=d|nid=1nd[(nd,id)=1]id=12(1+d|ndφ(d))

G(n)=2F(n)n ,则
G(n)=2F(n)n=i=1nd|idφ(d)=i=1nd=1nidφ(d)

因此要求的是 ϕ(n)=ni=1iφ(i)
而对于 n=ti=1pkii ,有
d|ndφ(d)=i=1tj=0kipjiφ(pji)=i=1tp2ki+1i+1pi+1
这并不是什么好算前缀和的函数。
但是不难发现 (idφ)id=id2 ,即
d|ndφ(d)nd=nd|nφ(d)=n2
,这是一个很好计算前缀和的函数,于是有
n(n+1)(2n+1)6=i=1ni2=i=1nd|idφ(d)id=id=1nidd=1niddφ(d)=i=1niϕ(ni)

因此 ϕ(n)=n(n+1)(2n+1)6ni=2iϕ(ni) ,原问题可在预处理前 O(n23) 个值的基础上,在 O(n23logn) 的时间复杂度下解决。

但是注意到这种方法的常数与复杂度都可能较高,有时候可能再进行一些推导可以得到一个不使用正文方法的做法,例如ZOJ 3881 - From the ABC conjecture,网上存在一个解法是类似本文的方法,但是可以这样推导之后得到更简单的一个做法。

需要使用此种方法的题目一般数据规模较大,例如 n109,n1011,n1012 ,但是并不是都要使用此类方法,有时候可能存在其他 O(n),O(n23) 的做法,例如51Nod 1222 - 最小公倍数计数,会利用正文复杂度分析的方法即可,再例如ZOJ 5340 - The Sum of Unitary Totient,笔者不是很懂这题是否有其他做法能过,例如 O(n34logn) 的积性函数求和方法(会在不久后更新),可能会因为数据组数较多而超时,网上的一个解法是分段压缩打表,具体问题需要具体分析。


推荐题目

这里给出一些练手的题目供大家理解上述方法,这类题还是较少的,如有其他题的题源欢迎分享。
51Nod 1244 - 莫比乌斯函数之和
51Nod 1239 - 欧拉函数之和
BZOJ 3944 - Sum
HDU 5608 - function
51Nod 1238 - 最小公倍数之和 V3
51Nod 1237 - 最大公约数之和 V3
51Nod 1227 - 平均最小公倍数
Tsinsen A1231 - Crash的数字表格
SPOJ DIVCNT2 - Counting Divisors (square)
51Nod 1222 - 最小公倍数计数(复杂度分析)
BZOJ 4176 - Lucas的数论
51Nod 1220 - 约数之和
51Nod 1584 - 加权约数和
ZOJ 3881 - From the ABC conjecture(不需要使用正文方法)
BZOJ 3512 - DZY Loves Math IV
ZOJ 5340 - The Sum of Unitary Totient(分段打表)
SPOJ DIVCNT3 - Counting Divisors (cube)(常规积性函数求和)
51Nod 1575 - Gcd and Lcm(综合题)

相关文章:

  • Codeforces Round #363 (Div. 2)[B]One Bomb
  • BFS、双向BFS和A*
  • 二分的模板(花式二分)
  • STL之set集合容器
  • NOIP2016#模拟考试 Day.1# T1 洗澡
  • NOIP2016#模拟考试 Day.1# T3 导航软件
  • [hdu 4405] Aeroplane chess [概率DP 期望]
  • NOIP2016#模拟考试 Day.2# T2 网络修复 【LCA + 并查集】
  • NOIP2016#模拟考试 Day.2# T3 王位继承
  • [hdu 2826] The troubles of lmy [简单计算几何 - 相似]
  • [hdu 2896] 病毒侵袭 [ac自动机][病毒特征码匹配]
  • [hdu 3065] 病毒侵袭持续中 [AC自动机] [病毒特征码匹配]
  • TCP/IP协议讲解 一
  • #NOIP 2014# day.1 生活大爆炸版 石头剪刀布
  • #NOIP 2014# day.1 T2 联合权值
  • 0基础学习移动端适配
  • Brief introduction of how to 'Call, Apply and Bind'
  • const let
  • CSS 专业技巧
  • Docker 笔记(1):介绍、镜像、容器及其基本操作
  • Effective Java 笔记(一)
  • JavaScript 是如何工作的:WebRTC 和对等网络的机制!
  • JavaScript工作原理(五):深入了解WebSockets,HTTP/2和SSE,以及如何选择
  • JavaSE小实践1:Java爬取斗图网站的所有表情包
  • JSONP原理
  • mysql外键的使用
  • PHP那些事儿
  • Redash本地开发环境搭建
  • spark本地环境的搭建到运行第一个spark程序
  • Vue全家桶实现一个Web App
  • windows下使用nginx调试简介
  • WordPress 获取当前文章下的所有附件/获取指定ID文章的附件(图片、文件、视频)...
  • 码农张的Bug人生 - 初来乍到
  • 与 ConTeXt MkIV 官方文档的接驳
  • 在 Chrome DevTools 中调试 JavaScript 入门
  • PostgreSQL之连接数修改
  • ​第20课 在Android Native开发中加入新的C++类
  • ​软考-高级-信息系统项目管理师教程 第四版【第19章-配置与变更管理-思维导图】​
  • "无招胜有招"nbsp;史上最全的互…
  • # 执行时间 统计mysql_一文说尽 MySQL 优化原理
  • #{} 和 ${}区别
  • $ git push -u origin master 推送到远程库出错
  • $HTTP_POST_VARS['']和$_POST['']的区别
  • (3)选择元素——(17)练习(Exercises)
  • (SpringBoot)第二章:Spring创建和使用
  • (zz)子曾经曰过:先有司,赦小过,举贤才
  • (分布式缓存)Redis持久化
  • (附源码)python旅游推荐系统 毕业设计 250623
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理 第13章 项目资源管理(七)
  • (南京观海微电子)——I3C协议介绍
  • (七)理解angular中的module和injector,即依赖注入
  • .CSS-hover 的解释
  • .net core 微服务_.NET Core 3.0中用 Code-First 方式创建 gRPC 服务与客户端
  • .NET delegate 委托 、 Event 事件
  • .NET Micro Framework初体验(二)