积性函数及其初级应用

积性函数及其初级应用

垃圾博客,我本地 LaTeX 挂了,艹

大量内容和入门方式都参考了 莫比乌斯反演与数论函数 。感谢 CMD 大爷!

0xFF 前置知识

1.质数及其判定,质因数及其分解

小学课本里面讲过质数的定义了,不细讲。分解质因数也是基本功。

2.筛法

同学们想必都会埃氏筛法吧,即对于每一个质数枚举其倍数筛除整个值域内的所有数。

如果你学得更远一点,那么你会使用欧拉筛法。它的算法思想这里不再赘述。

后面的一切练习题都是基于欧拉筛的。所以这个基本功也要打好。

3.唯一分解定理

所以一个正整数可以分解成为 p 1 k 1 p 2 k 2 . . . p m k m p_1^{k_1}p_2^{k_2}...p_m^{k_m} p1k1p2k2...pmkm 的形式, p p p 为质数而且两两不重复。这个分解对于每个 n n n 都是唯一的,我们称之为正整数的唯一分解定理

比如 1800 = 2 3 × 3 2 × 5 2 1800=2^3\times 3^2\times 5^2 1800=23×32×52 1 1 1 就直接是 1 1 1(但是分解不出质数,所以其 m = 0 m=0 m=0)。

4.命题与定理证明等

在我们的世界之中,有许许多多的真理,比如太阳从东边升起西边落下,两点确定一条直线,勾股定理。这就叫做真命题

有了真命题就有了假命题:比如水是剧毒的。(什么思想钢印)

在这些许许多多真命题之中,在人类长期的科学实践之中,不需要再加以证明的命题,就是公理。比如两点确定一条直线。

需要通过这些基本事实,需要加以证明的真命题,叫做定理。比如勾股定理,没有人规定这是一条公理,但是它已经被各种花样的方法证明出来了。

证明是什么?在这里出现了许多次了。它是在一个特定的公理系统中,根据一定的规则或标准,由公理定理推导出某些命题的过程。上了初中,你会碰到一系列复杂的证明题

另外,逆命题其实就是一个命题的条件结论反过来。比如勾股定理是在直角三角形之内斜边长为 c c c a 2 + b 2 = c 2 a^2+b^2=c^2 a2+b2=c2,它的逆命题就是如果在一个三角形之内满足 a 2 + b 2 = c 2 a^2+b^2=c^2 a2+b2=c2 那么这个三角形就是直角三角形, c c c 所对的那个角是直角。显然,勾股定理的逆命题是成立的。

但是一个真命题逆命题不一定是真命题。比如等边三角形有一个角是 60 60 60 度,但是只有一个角是 60 60 60 度的三角形不一定是等边三角形。

呼,累死了,终于写完了,下课休息

5.本文所使用的一些符号和运算

a b a^b ab 表示 a a a b b b 次方(就是 b b b a a a 相乘的乘积)。比如 2 3 = 2 × 2 × 2 2^3=2\times 2\times 2 23=2×2×2 5 4 = 5 × 5 × 5 × 5 5^4=5\times 5\times 5\times 5 54=5×5×5×5

d ∣ n d|n dn:表示 d d d 整除 n n n n n n d d d 的倍数。比如 1 ∣ 10 , 2 ∣ 6 1|10,2|6 1∣10,2∣6 但是 3 3 3 不整除 5 5 5

∑ \sum :求和,其实就是一个类似于枚举的过程。比如 ∑ i = 1 n \sum_{i=1}^n i=1n 就是枚举整数 i i i 1 1 1 n n n,而 ∑ d ∣ x \sum_{d|x} dx 就是枚举 x x x 的约数。

它的值就是对于和式后面的结果之和。比如 ∑ i = 1 10 i = 55 \sum_{i=1}^{10} i=55 i=110i=55

在本文之内,我使用这个除号 / / / 作为整除,如无法整除就下取整。但是比如 O ( n 2 / 3 ) O(n^{2/3}) O(n2/3) 显然就是表达 O ( n 2 3 ) O(n^{\frac{2}{3}}) O(n32)

在本文之内,我使用 ( x , y ) (x,y) (x,y) 作为 gcd ⁡ ( x , y ) \gcd(x,y) gcd(x,y) 的值。

在本文之内,计 [ x ] [x] [x] 表示 x x x 成立则为 1 1 1,否则则为 0 0 0。比如 [ 我是蒟蒻 ] = 1 [\texttt{我是蒟蒻}]=1 [我是蒟蒻]=1

本文中,章节使用十六进制编号。

0x00 例题引入 ZAP-Queries

P3455 [POI2007]ZAP-Queries

题目大意:有 n n n 组询问,每组询问求 ∑ i = 1 a ∑ j = 1 b [ ( i , j ) = c ] \sum_{i=1}^a\sum_{j=1}^b[(i,j)=c] i=1aj=1b[(i,j)=c]

我们想到了一个非常暴力的方法,直接枚举 a a a b b b,然后 O ( log ⁡ n ) O(\log n) O(logn) 做一遍 gcd ⁡ \gcd gcd,判断能不能成!时间复杂度 O ( a b log ⁡ d ) O(ab\log d) O(ablogd)

但是 1 ≤ n , a , b , d ≤ 5 × 1 0 4 1\le n,a,b,d\le 5\times 10^4 1n,a,b,d5×104 我该怎么办呢?

聪明的同学可能会想,只要我 ( i , j ) = c (i,j)=c (i,j)=c 就行,那么显然 i , j i,j i,j c c c 的倍数。

可是只满足 ( i , j ) (i,j) (i,j) c c c 的倍数还是不够,因为它们可能不互质。

[ 1 , a ] [1,a] [1,a] 之中, c c c 的倍数有 a / c a/c a/c 个;同理可得 [ 1 , b ] [1,b] [1,b] 之中 c c c 的倍数有 b / c b/c b/c 个。

a ′ = a / c , b ′ = b / c a'=a/c,b'=b/c a=a/c,b=b/c,问题就变成了统计 ∑ i = 1 a ′ ∑ j = 1 b ′ [ ( i , j ) = 1 ] \sum_{i=1}^{a'}\sum_{j=1}^{b'}[(i,j)=1] i=1aj=1b[(i,j)=1]

但是这个还是比较麻烦,我们应该如何处理?

这类关于互质, gcd ⁡ \gcd gcd 的题目,就是今天的积性函数所解决的。

0x10 积性函数的基础知识

这一节主要是对概念的理解,相信小学同学和中学的同学理解起来都不会很困难。

0x11 迪利克雷卷积

概念:两个函数 f ( x ) f(x) f(x) g ( x ) g(x) g(x) 的迪利克雷卷积为 ∑ d ∣ x f ( d ) g ( x / d ) \sum_{d|x} f(d)g(x/d) dxf(d)g(x/d)

写法就是 ( f ∗ g ) ( x ) (f*g)(x) (fg)(x)

基本特性:满足交换律,结合律。它具有对称性。

下面简称卷积

0x12 几个简单函数

恒等函数 I ( n ) I(n) I(n):无论 n n n 是啥都返回 1 1 1

元函数 e ( n ) e(n) e(n):当 n = 1 n=1 n=1 时返回 1 1 1,其他情况返回 0 0 0

它的特殊性质是 f ( n ) f(n) f(n) e ( n ) e(n) e(n) 做迪利克雷卷积时候就是 f ( n ) f(n) f(n)

单位函数 i d ( n ) id(n) id(n):返回 n n n

它的衍生,幂函数: i d x ( n ) id^x (n) idx(n):返回 n x n^x nx

这几个函数都是完全积性函数。

0x13 积性函数的定义

如果 gcd ⁡ ( a , b ) = 1 \gcd(a,b)=1 gcd(a,b)=1 f ( a b ) = f ( a ) f ( b ) f(ab)=f(a)f(b) f(ab)=f(a)f(b) 则这个函数为 积性函数

完全积性函数的规矩更严格,去掉了 gcd ⁡ ( a , b ) = 1 \gcd(a,b)=1 gcd(a,b)=1 的性质。

一些基础性质:积性函数 f f f 要求 f ( 1 ) = 1 f(1)=1 f(1)=1,因为对于 f ( n ) f(n) f(n) 满足 f ( n ) = f ( n ) f ( 1 ) f(n)=f(n)f(1) f(n)=f(n)f(1)

0x14 稍微复杂的数论函数

欧拉函数 φ ( n ) \varphi(n) φ(n)小于 n n n 的所有正整数之中和 n n n 互质数的个数。特别地,对于 φ ( 1 ) = 1 \varphi(1)=1 φ(1)=1

(可以先不用掌握)莫比乌斯函数 μ ( n ) \mu(n) μ(n) n n n 被唯一分解成 p 1 k 1 p 2 k 2 . . . p m k m p_1^{k_1}p_2^{k_2}...p_m^{k_m} p1k1p2k2...pmkm 的形式,其中任意一个 k i k_i ki 大于 1 1 1 则函数值为 0 0 0。否则,如果 m m m 为奇数则为 − 1 -1 1 m m m 为偶数(包括 0 0 0)则为 1 1 1

这两个都是积性函数,它的证明之后会涉及。

0x15 积性函数的一些定理及其证明

定理1:积性函数的唯一分解性质。如果 n n n 能够唯一分解成为 p 1 k 1 p 2 k 2 . . . p m k m p_1^{k_1}p_2^{k_2}...p_m^{k_m} p1k1p2k2...pmkm 的形式(唯一分解:所有 p p p 为质数因子,且 p p p 互不相同),那么积性函数 f ( n ) = f ( p 1 k 1 ) f ( p 1 k 2 ) . . . f ( p m k m ) f(n)=f(p_1^{k^1})f(p_1^{k_2})...f(p_m^{k_m}) f(n)=f(p1k1)f(p1k2)...f(pmkm)

证明:因为质因子两两互质,所以可以通过积性函数的性质来达成唯一分解的效果。

运用:求解欧拉函数。

定理2:积性函数的卷积还是积性函数。比如 F 1 ( x ) F_1(x) F1(x) F 2 ( x ) F_2(x) F2(x) 卷积起来就是 G ( x ) G(x) G(x),求证 G G G 是积性函数。

来自 CMD 大爷的证明:设两数 a , b a,b a,b 互质。
G ( a ) G ( b ) G(a)G(b) G(a)G(b)
= ∑ d ∣ a F 1 ( d ) F 2 ( a / d ) ∗ ∑ t ∣ b F 1 ( t ) F 2 ( b / t ) =\sum\limits_{d|a}F_1(d)F_2(a/d)*\sum\limits_{t|b}F_1(t)F_2(b/t) =daF1(d)F2(a/d)tbF1(t)F2(b/t)
= ∑ d ∣ a ∑ t ∣ b F 1 ( d ) F 2 ( a / d ) 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) =datbF1(d)F2(a/d)F1(t)F2(b/t)
我们发现因为 b b b a a a 互质所以 t t t d d d 互质。
= ∑ d t ∣ a b F 1 ( d t ) F 2 ( a b / d t ) =\sum\limits_{dt|ab} F_1(dt)F_2(ab/dt) =dtabF1(dt)F2(ab/dt)
= G ( a b ) =G(ab) =G(ab)。得证。

0x1F 小小练习

1.计算当 x = 12 x=12 x=12 时, f ( x ) = x + 1 f(x)=x+1 f(x)=x+1 g ( x ) = x 2 − 2 g(x)=x^2-2 g(x)=x22 的迪利克雷卷积的值~~(我知道,这两个东西不是数论函数,别骂了别骂了)~~。

2.证明恒等函数、元函数、单位函数的完全积性。

(想必大家都会)

定理3.积性函数的逆也是积性函数。

积性函数的逆:满足 e = g ∗ f e=g*f e=gf 时候, g g g f f f 互逆。

(我不会证明,留作作业)

0x20 重新定义几个积性函数

这一部分当时不求甚解,像是小鲁迅背《鉴略》。

0x21 重新认识莫比乌斯函数

在日常生活之中,我们往往运用 F ( x ) = ∑ d ∣ x f ( x ) F(x)=\sum_{d|x}f(x) F(x)=dxf(x)。可得 F = I ∗ f F=I*f F=If

如果这个 f ( x ) f(x) f(x) 超级好求那么我的 F F F 也比较好求。

但是现实生活之中往往 f ( x ) f(x) f(x) 比较难求而 F ( x ) F(x) F(x) 比较好求。

f = I − 1 ∗ F f=I^{-1}*F f=I1F,我该怎么处理这个 I − 1 I^{-1} I1 呢?

莫比乌斯称其为莫比乌斯函数 μ ( x ) \mu(x) μ(x)。定义上, μ ( x ) = I − 1 \mu(x)=I^{-1} μ(x)=I1,即 μ ( x ) ∗ I = e \mu(x)*I=e μ(x)I=e

后面那个式子的结论其实就是 ∑ d ∣ x μ ( x ) = e ( x ) \sum_{d|x}\mu(x)=e(x) dxμ(x)=e(x),在莫比乌斯反演之中经常使用到这个结论来表达元函数的值。

原来莫比乌斯函数有这么奇妙的性质!——鲁迅

0x22 莫比乌斯函数的推导

我们知道积性函数适用于唯一分解定理,所以不如研究一下 μ ( p k ) \mu(p^k) μ(pk) 的值是什么。

k = 0 k=0 k=0 时候因为 e ( 1 ) = 1 , I ( 1 ) = 1 e(1)=1,I(1)=1 e(1)=1,I(1)=1 所以自然的 μ ( 1 ) = 1 \mu(1)=1 μ(1)=1

k = 1 k=1 k=1 时候, e ( p ) = ∑ d ∣ p μ ( p ) I ( p ) = I ( p ) μ ( 1 ) + I ( 1 ) μ ( p ) = 0 e(p)=\sum_{d|p}\mu(p)I(p)=I(p)\mu(1)+I(1)\mu(p)=0 e(p)=dpμ(p)I(p)=I(p)μ(1)+I(1)μ(p)=0,我们知道 I ( p ) = 1 , μ ( 1 ) = 1 , I ( 1 ) = 1 I(p)=1,\mu(1)=1,I(1)=1 I(p)=1,μ(1)=1,I(1)=1 所以 μ ( p ) = − 1 \mu(p)=-1 μ(p)=1

(下列省略恒等函数)

k = 2 k=2 k=2 时候, e ( p 2 ) = μ ( p 2 ) + μ ( p ) + μ ( 1 ) = 0 e(p^2)=\mu(p^2)+\mu(p)+\mu(1)=0 e(p2)=μ(p2)+μ(p)+μ(1)=0,我们知道 μ ( 1 ) = 1 , μ ( p ) = − 1 \mu(1)=1,\mu(p)=-1 μ(1)=1,μ(p)=1 所以 μ ( p 2 ) = 0 \mu(p^2)=0 μ(p2)=0

可以再推下去,但是不再会变动,例如 e ( p 3 ) = μ ( p 3 ) + e ( p 2 ) e(p^3)=\mu(p^3)+e(p^2) e(p3)=μ(p3)+e(p2),可以得到 μ ( p 3 ) = 0 \mu(p^3)=0 μ(p3)=0

利用数学归纳法可证明 k > 1 k>1 k>1 时候 μ ( p k ) = 0 \mu(p^k)=0 μ(pk)=0

所以, μ ( 1 ) = 1 , μ ( p ) = − 1 , μ ( p k ( k ≥ 2 ) ) = 0 \mu(1)=1,\mu(p)=-1,\mu(p^{k_{(k\ge 2)}})=0 μ(1)=1,μ(p)=1,μ(pk(k2))=0

我们知道莫比乌斯函数是 I − 1 I^{-1} I1,运用定理2,一个积性函数的逆元仍然是一个积性函数,所以它是一个积性函数。

唯一分解一下 n n n,令 n = p 1 k 1 p 2 k 2 . . . p m k m n=p_1^{k_1}p_2^{k_2}...p_m^{k_m} n=p1k1p2k2...pmkm,得出 μ ( n ) = μ ( p 1 k 1 ) μ ( p 2 k 2 ) . . . μ ( p m k m ) \mu(n)=\mu(p_1^{k_1})\mu(p_2^{k_2})...\mu(p_m^{k_m}) μ(n)=μ(p1k1)μ(p2k2)...μ(pmkm)

根据定理1,如果其中有一个 k > 1 k>1 k>1 μ ( n ) = 0 \mu(n)=0 μ(n)=0,否则 μ ( n ) = ( − 1 ) m \mu(n)=(-1)^m μ(n)=(1)m

综上所述,我们就得到了莫比乌斯函数的定义。好神奇!

0x23 欧拉函数的积性及其定义

上一课刚刚讲过,欧拉函数的定义是 φ ( n ) \varphi(n) φ(n) [ 1 , n − 1 ] [1,n-1] [1,n1] 之中与它互质数的个数(特别地, φ ( 1 ) = 1 \varphi(1)=1 φ(1)=1)。利用 CRT 可以证明,在此不作展开。

按照莫比乌斯函数的推导,显然 φ ( p k ) = p k ( p − 1 ) / p \varphi(p^k)=p^k(p-1)/p φ(pk)=pk(p1)/p,因为容斥原理可得。

所以唯一分解一下 n n n,令 n = p 1 k 1 p 2 k 2 . . . p m k m n=p_1^{k_1}p_2^{k_2}...p_m^{k_m} n=p1k1p2k2...pmkm,得出 φ ( n ) = n ( p 1 − 1 ) ( p 2 − 1 ) . . . ( p m − 1 ) p 1 p 2 . . . p m \varphi(n)=n\dfrac{(p_1-1)(p_2-1)...(p_m-1)}{p_1p_2...p_m} φ(n)=np1p2...pm(p11)(p21)...(pm1)

所以,如果我们知道 n n n 的质因数分解,就可以得出 φ ( n ) \varphi(n) φ(n) 了。

0x2F 课后作业-程序实现题

**应用题:**1.欧拉函数的实际求解

(1)对于一个 n n n ,如果我有 n n n 的质因数分解方式,如何做到 O ( log ⁡ n ) O(\log n) O(logn) 求解?

(2)如果我要求的值域范围 n n n 比较小,但是我需要比较快地访问,实现 O ( n ) O(n) O(n) 预处理, O ( 1 ) O(1) O(1) 查询,又该怎么办?

有同学说这是线性筛,这就对啦。就是设计一个算法线性筛欧拉函数。

2.莫比乌斯函数的实际求解

(1)对于一个 n n n,如果我有 n n n 的质因数分解方式,如何做到 O ( log ⁡ n ) O(\log n) O(logn) 求解?

(2)我该怎么线性筛莫比乌斯函数

0x30 莫比乌斯函数和其简单应用

0x31 各种小转化

e ( x ) e(x) e(x):我们知道 e = I ∗ μ e=I*\mu e=Iμ,所以可得 e ( x ) = ∑ d ∣ x μ ( d ) e(x)=\sum_{d|x}\mu(d) e(x)=dxμ(d)

实际应用:如果我需要和式里面 n = m n=m n=m 的条件,那么就是 [ n ∣ m ] e ( n / m ) [n|m]e(n/m) [nm]e(n/m),即 [ n ∣ m ] ∑ d ∣ ( n / m ) μ ( d ) [n|m]\sum_{d|(n/m)}\mu(d) [nm]d(n/m)μ(d)

这个称作**“嵌入式反演”**。

回到之前的 F ( x ) = ∑ d ∣ x f ( x ) F(x)=\sum_{d|x}f(x) F(x)=dxf(x):根据莫比乌斯函数的定义可得, f ( x ) = ∑ d ∣ x μ ( x ) F ( x / d ) f(x)=\sum_{d|x}\mu(x)F(x/d) f(x)=dxμ(x)F(x/d)。这个就是因数的莫比乌斯反演

如果我是倍数的莫比乌斯反演,即 F ( x ) = ∑ x ∣ d f ( x ) F(x)=\sum_{x|d}f(x) F(x)=xdf(x) 呢?那么其实也是 f ( x ) = ∑ x ∣ d μ ( d / x ) F ( x ) f(x)=\sum_{x|d}\mu(d/x)F(x) f(x)=xdμ(d/x)F(x)

这个证明我不会。

0x32 简单的例题!

前面讲了那么多理论知识相比大家都睡着觉了吧,不如来一道例题练手。

P3455 [POI2007]ZAP-Queries

题意:上面已经给出了。

我们现在要求 ∑ i = 1 a ′ ∑ j = 1 b ′ [ ( i , j ) = 1 ] \sum_{i=1}^{a'}\sum_{j=1}^{b'}[(i,j)=1] i=1aj=1b[(i,j)=1]

Tips:在处理 a ′ a' a b ′ b' b 的时候往往会让 a ′ < b ′ a'a<b,如果不符合就交换即可。

我的手上有三把宝刀,因数的莫反,倍数的莫反,还有嵌入式反演。

这里因为是条件 = 1 =1 =1 的形式,所以我们使用嵌入式反演进行推导。

原式= ∑ i = 1 a ′ ∑ j = 1 b ′ ∑ d ∣ ( i , j ) μ ( d ) \sum_{i=1}^{a'}\sum_{j=1}^{b'}\sum_{d|(i,j)}\mu(d) i=1aj=1bd(i,j)μ(d)

这个式子变得更加复杂,不好求?没关系,我们调换求和顺序!

发现 d d d 其实在 [ 1 , a ′ ] [1,a'] [1,a] 之内,而 i , j i,j i,j 无非就是 d d d 的倍数。

所以原式= ∑ d = 1 a ′ μ ( d ) ∑ i = 1 a ′ ∑ j = 1 b ′ [ d ∣ i ] [ d ∣ j ] \sum_{d=1}^{a'}\mu(d)\sum_{i=1}^{a'}\sum_{j=1}^{b'} [d|i][d|j] d=1aμ(d)i=1aj=1b[di][dj]

后面那坨形式直接转化一下,实际上就是一个数字,即 ( a ′ / d ) ( b ′ / d ) (a'/d)(b'/d) (a/d)(b/d)

那么原式= ∑ d = 1 a ′ μ ( d ) ( a ′ / d ) ( b ′ / d ) \sum_{d=1}^{a'}\mu(d)(a'/d)(b'/d) d=1aμ(d)(a/d)(b/d)

至此,我们把这个式子神奇地转化成为了 O ( a ′ ) O(a') O(a) 的形式!

但是发现还是太慢了,毕竟这题有许多询问。

发现这样一个事情: d d d 在一段区间内,能够使得 ( a ′ / d ) ( b ′ / d ) (a'/d)(b'/d) (a/d)(b/d) 相同,这样的话就可以利用整除分块+前缀和计算 μ \mu μ 和的方法进行优化。能够直接优化到 O ( n a ′ ) O(n\sqrt {a'}) O(na ) 的级别。

const I lim=5e4;
const I N=5e4+10;
bool p[N];
I pr[N],pl,mu[N],smu[N],q,a,b,d;
LL solve(I a,I b){
	LL ans=0;
	for(I l=1,r=0;l<=a;l=r+1){
		r=min(a/(a/l),b/(b/l));
		ans+=1ll*(smu[r]-smu[l-1])*(a/l)*(b/l);}
	return ans;}
I main(){
	mu[1]=1;smu[1]=1;
	for(I i=2;i<=lim;++i){
		if(!p[i])pr[++pl]=i,mu[i]=-1;
		for(I j=1;j<=pl&&1ll*pr[j]*i<=lim;++j){
			p[pr[j]*i]=1;
			if(i%pr[j]==0){
				mu[i*pr[j]]=0;
				break;}
			mu[i*pr[j]]=-mu[i];}
		smu[i]=smu[i-1]+mu[i];}
	in(q);
	while(q--){
		in(a,b,d);a/=d;b/=d;
		if(a>b)swap(a,b);
		printf("%lld\n",solve(a,b));}
	return 0;
}

0x33 简单的小练习

P2158 [SDOI2008] 仪仗队

题意:求一个人站在 n × n n\times n n×n 的矩阵的左下角能够看到多少个人(被挡住的不算)。

算法:莫比乌斯反演,或者欧拉函数。

P2522 [HAOI2011]Problem b

题意:求 ∑ i = a b ∑ j = c d [ ( i , j ) = k ] \sum_{i=a}^{b}\sum_{j=c}^{d}[(i,j)=k] i=abj=cd[(i,j)=k]

算法:莫比乌斯反演,并且利用二维差分的思想。

上述小练习应该很容易通过,所以不做赘述。

拿行李(极限版) GCD - Extreme (II)

GCDEX - GCD Extreme

0x34 稍微复杂的例题

P2568 GCD

题意:求 ∑ i = 1 n ∑ j = 1 n [ ( x , y ) ∈ prime ] \sum_{i=1}^n\sum_{j=1}^n [(x,y)\in \text{prime}] i=1nj=1n[(x,y)prime]

依旧按照之前的套路。我们枚举 ( x , y ) (x,y) (x,y) 设之为 g g g,然后求解 ∑ g ∈ prime n ∑ i = 1 n / g ∑ j = 1 n / g [ ( i , j ) = 1 ] \sum_{g\in\text{prime}}^n \sum_{i=1}^{n/g}\sum_{j=1}^{n/g}[(i,j)=1] gprimeni=1n/gj=1n/g[(i,j)=1]

利用嵌入式反演的套路,最后的式子是 ∑ g ∈ prime n ∑ d = 1 n / g μ ( d ) ( n / g / d ) 2 \sum_{g\in \text{prime}}^n\sum_{d=1}^{n/g}\mu(d) (n/g/d)^2 gprimend=1n/gμ(d)(n/g/d)2

但是 n ≤ 1 0 7 n\le 10^7 n107,对于每个求解整除分块有可能会超时?实际上不会。

cmd大爷:我们来事前分析一下时间复杂度。

O ( ∑ g ∈ prime n n / p ) = O ( n ∑ g ∈ prime n 1 g ) = O ( n 1 log ⁡ n ∑ p = 1 n 1 p ) O(\sum_{g\in{\text{prime}}}^n\sqrt{n/p})\\=O(\sqrt{n}\sum_{g\in\text{prime}}^n\sqrt{\dfrac{1}{g}})\\=O(\sqrt n\dfrac{1}{\log n}\sum_{p=1}^n \sqrt{\dfrac{1}{p}}) O(gprimenn/p )=O(n gprimeng1 )=O(n logn1p=1np1 )

运用积分知识,

= O ( n 1 log ⁡ n n ) = O ( n / log ⁡ n ) =O(\sqrt n\dfrac{1}{\log n}\sqrt n)\\=O(n/\log n) =O(n logn1n )=O(n/logn)

于是这就结束了,而且程序跑得不慢。

实际上可以计算一下这个式子的操作次数,即事后计算效率法,对于这种时间复杂度式子非常复杂的可以一用。

Talk is Cheap,Show me the Code。

const I N=1e7+10,lim=1e7;
bitset<N>p;
I pr[1000000],pl,n,mu[N],smu[N]; 
LL ans;
LL calc(I x){
	LL ans=0;
	for(I l=1,r=0;l<=x;l=r+1){
		r=x/(x/l);
		ans+=1ll*(smu[r]-smu[l-1])*(x/l)*(x/l);}
	return ans;}
I main(){
	in(n);
	smu[1]=mu[1]=1;
	for(I i=2;i<=n;++i){
		if(!p[i])pr[++pl]=i,mu[i]=-1;
		for(I j=1;1ll*pr[j]*i<=n;++j){
			p[pr[j]*i]=1;
			if(i%pr[j]==0){
				mu[i*pr[j]]=0;break;}
			mu[i*pr[j]]=-mu[i];}
		smu[i]=smu[i-1]+mu[i];}
	for(I i=1;i<=pl;++i){
		I g=pr[i];
		ans+=calc(n/g);}
	printf("%lld\n",ans);
	return 0;
}

P2257 YY的GCD

!比上题加了多组询问,怎么处理?(假设 n ≤ m n\le m nm

继续改变式子, ∑ g ∈ prime n ∑ d = 1 n / g μ ( d ) ( n / g / d ) ( m / g / d ) \sum_{g\in \text{prime}}^n\sum_{d=1}^{n/g}\mu(d) (n/g/d)(m/g/d) gprimend=1n/gμ(d)(n/g/d)(m/g/d) 考虑枚举 g d gd gd 设之为 k k k

原式= ∑ k = 1 n ∑ g ∈ prime , g ∣ k n μ ( k / g ) ( n / k ) ( m / k ) \sum_{k=1}^n\sum_{g\in\text{prime},g|k}^n \mu(k/g)(n/k)(m/k) k=1ngprime,gknμ(k/g)(n/k)(m/k)

考虑把 μ \mu μ 放在后面,原式= ∑ k = 1 n ( n / k ) ( m / k ) ∑ g ∈ p r i m e , g ∣ k μ ( k / g ) \sum_{k=1}^n (n/k)(m/k)\sum_{g\in prime,g|k}\mu(k/g) k=1n(n/k)(m/k)gprime,gkμ(k/g)

前面可以整除分块弄,后面这部分也比较简单。

我们观察 g g g k k k 的因子,且 g g g 是质数,那么 g g g k k k 的所有质因数。

一个数的质因数个数最多只有 log ⁡ n \log n logn 级别(实际还不到,毕竟 1 0 9 10^9 109 里面也就最多 9 9 9 个),我们可以通过枚举质数再枚举其倍数直接贡献的方式来处理质因子。

所以总时间复杂度是 O ( t n + n log ⁡ log ⁡ n ) O(t\sqrt n +n\log \log n) O(tn +nloglogn)。实际上很快。

const I mxn=1e7;
I pr[1000010],pl,ans[10000010];LL ss[10000010];
short mu[10000010];
bitset<10000010>np;
I n,m;I sqr(I x){return x*x;}
I main(){
	mu[1]=1;
	for(I i=2;i<=mxn;++i){
		if(!np[i])pr[++pl]=i,mu[i]=-1;
		for(I j=1,im;j<=pl&&1ll*i*pr[j]<=mxn;++j){
			im=i*pr[j];
			np[im]=1;
			if(i%pr[j]==0){
				mu[im]=0;
				break;
			}mu[im]=mu[i]*-1;
		}
	}
	for(I i=1;i<=pl;++i)for(I j=1;pr[i]*1ll*j<=mxn;++j)ans[j*pr[i]]+=mu[j];
	for(I i=1;i<=mxn;++i)ss[i]=ss[i-1]+ans[i];
	I T;in(T);while(T--){
		in(n,m);
		if(n>m)swap(n,m);
		I l=1,r=0,ndl,mdl;LL an=0;
		while(l<=n){
			r=min(n/(ndl=n/l),m/(mdl=m/l));
			an+=1ll*ndl*mdl*(ss[r]-ss[l-1]);
			l=r+1;
		}
		printf("%lld\n",an);
	}
	return 0;
}

P5221 Product

∏ i = 1 n ∏ j = 1 n lcm(i,j) gcd ⁡ ( i , j ) \prod_{i=1}^n \prod_{j=1}^n \dfrac{\text{lcm(i,j)}}{\gcd(i,j)} i=1nj=1ngcd(i,j)lcm(i,j)。取模 100 × 2 20 + 1 100\times 2^{20}+1 100×220+1。(是一个质数!)

根据套路我们可以算出原式= ( n ! ) 2 n ( ∏ g = 1 n g ∑ d ∣ ( n / g ) μ ( d ) ( n / g / d ) 2 ) − 2 (n!)^{2n}(\prod_{g=1}^n g^{\sum_{d|(n/g)}\mu(d)(n/g/d)^2})^{-2} (n!)2n(g=1ngd(n/g)μ(d)(n/g/d)2)2,上面那坨指数可以根号去算,总共时间复杂度 O ( 能过 ) O(\texttt{能过}) O(能过)

const I N=1e6+10,lim=1e6,mod=104857601;
bitset<N>p;
I smu[N],pr[N],pl,n;
I mul(I x,I y){
	return 1ll*x*y%mod;}
I pw(I x,I y){
	I ans=1;
	for(;y;y>>=1,x=mul(x,x))if(y&1)ans=mul(ans,x);
	return ans;}
I su(I x){
	LL ans=0;
	for(I l=1,r=0;l<=x;l=r+1){
		r=x/(x/l);
		ans=(ans+1ll*((smu[r]-smu[l-1])%(mod-1)+mod-1)%(mod-1)*(x/l)*(x/l)%(mod-1))%(mod-1);
		ans%=(mod-1);}
	return ans;}
I main(){
	in(n);
	smu[1]=1;
	for(I i=2;i<=n;++i){
		if(!p[i])pr[++pl]=i,smu[i]=-1;
		for(I j=1;j<=pl&&1ll*pr[j]*i<=n;++j){
			p[i*pr[j]]=1;
			if(i%pr[j]==0){
				smu[i*pr[j]]=0;
				break;}
			smu[i*pr[j]]=-smu[i];}}
	for(I i=2;i<=n;++i){
		smu[i]+=smu[i-1];}
	I facn=1,fm=1;
	for(I i=1;i<=n;++i)facn=mul(facn,i);
	for(I g=1;g<=n;++g){
		fm=mul(fm,pw(g,su(n/g)));}
	fm=mul(fm,fm);
	fm=pw(fm,mod-2);
	printf("%d\n",mul(pw(facn,2ll*n%(mod-1)),fm));
	return 0;
}

注意负数!

可以在 luogu 上寻找相关例题去实现。

0x3F 课后作业-程序实现题

(OK)P1447 [NOI2010] 能量采集

(OK)P2398 GCD SUM

(OK)P1390 公约数的和

(N/A)P3704 [SDOI2017]数字表格

作业题的代码请同学们自行实现。

0x40 欧拉函数及其简单应用

0x41 一些小转化

1. φ ∗ I = i d \varphi*I=id φI=id

证明:假设 n = p c n=p^c n=pc,其中 p p p 为质数。

φ ( n ) ∗ I = ∑ d ∣ n φ ( d ) = ∑ i = 0 c φ ( p i ) = 1 + ( p − 1 ) + p ( p − 1 ) + p 2 ( p − 1 ) + . . . + p c − 1 ( p − 1 ) = p + p ( p − 1 ) + p 2 ( p − 1 ) + . . . = p 2 + p 2 ( p − 1 ) + . . . = p c = i d ( p ) \varphi(n)*I=\sum_{d|n}\varphi(d)\\=\sum_{i=0}^{c}\varphi(p^i)\\=1+(p-1)+p(p-1)+p^2(p-1)+...+p^{c-1}(p-1)\\=p+p(p-1)+p^2(p-1)+...\\=p^2+p^2(p-1)+...\\=p^c\\=id(p) φ(n)I=dnφ(d)=i=0cφ(pi)=1+(p1)+p(p1)+p2(p1)+...+pc1(p1)=p+p(p1)+p2(p1)+...=p2+p2(p1)+...=pc=id(p)

因为 φ \varphi φ 是一个积性函数,所以对于任意的 φ ( x ) \varphi(x) φ(x) 都有效。故此命题得证。

有了这个问题可以做什么?

因为 φ ∗ I = i d \varphi*I=id φI=id,所以 i d ∗ I − 1 = φ id* I^{-1}=\varphi idI1=φ i d ∗ μ = φ id*\mu=\varphi idμ=φ

0x42 一道小例题

P2303 [SDOI2012] Longge 的问题

∑ i = 1 n gcd ⁡ ( i , n ) \sum_{i=1}^n\gcd(i,n) i=1ngcd(i,n)

按照套路,原式= ∑ g ∣ n g φ ( n / g ) \sum_{g|n} g\varphi(n/g) gngφ(n/g)

要处理 φ ( n / g ) \varphi(n/g) φ(n/g),不需要 O ( n ) O(\sqrt n) O(n ),只要我预跑一遍 O ( n ) O(\sqrt n) O(n ) 分解质因数的,再来看看这个 n / g n/g n/g 里面有哪几个质因子即可。

时间复杂度 O ( n × ln ⁡ ( n ) ) O(\sqrt n\times \ln(n)) O(n ×ln(n))

I n;
LL ans=0;
vector<I>v,e; 
void prework(I n){
	I nn=n;
	for(I i=2;1ll*i*i<=n;++i){
		if(n%i)continue;
		v.push_back(i);
		while(n%i==0)n/=i;
	}if(n>1)v.push_back(n);
	n=nn;
	for(I i=1;1ll*i*i<=n;++i){
		if(n%i)continue;
		e.push_back(i);
		if(i^(n/i))e.push_back(n/i);}
	sort(e.begin(),e.end());
    //这个其实没必要
}
I phi(I x){
	I ans=x;
	for(I i:v){
		if(x%i==0)ans=(ans/i)*(i-1);}
	return ans;}
int main(){
	in(n);
	prework(n);
	for(I i:e){
		ans+=1ll*i*phi(n/i);}
	printf("%lld\n",ans);
	return 0;
}

0x4F 一些小练习-程序实现题

拿行李(极限版) GCD - Extreme (II)

题意:求 ∑ i = 1 n − 1 ∑ j = i + 1 n gcd ⁡ ( i , j ) \sum_{i=1}^{n-1}\sum_{j=i+1}^n\gcd(i,j) i=1n1j=i+1ngcd(i,j)

这题转化一下,先是按照以往的套路,把它换成互质的形式。

当然这一次直接套欧拉函数前缀和,式子是 ∑ g = 1 n − 1 g × s u m ( n / g ) \sum_{g=1}^{n-1}g\times sum(n/g) g=1n1g×sum(n/g) s u m ( x ) sum(x) sum(x) [ 2 , x ] [2,x] [2,x] 所有欧拉函数之和)。

后面那部分显然可以整除分块做。

三倍经验:1,2,3

0x50 求和的利器——杜教筛

(OK)GCDEX2

题意:还是上面那道题目。但是此时 n n n 很大,不能 O ( n ) O(n) O(n) 去筛,而且也有很多查询之类的。

0x51 算法核心

s ( n ) = ∑ i = 1 n f ( i ) s(n)=\sum_{i=1}^n f(i) s(n)=i=1nf(i),我想超越线性。

我想构造一个函数 g g g 使得这个 s s s 应该能够用 s ( n ) = ∑ d ∣ x . . . s ( d ) s(n)=\sum_{d|x} ...s(d) s(n)=dx...s(d) 的形式表达出来。

套路: ∑ i = 1 n ( f ∗ g ) ( i ) = ∑ i = 1 n ∑ d ∣ i f ( i / d ) g ( d ) = ∑ d = 1 n g ( d ) ∑ i = 1 n / d f ( i ) = ∑ d = 1 n g ( d ) s ( n / d ) \sum_{i=1}^n (f*g)(i)\\=\sum_{i=1}^n\sum_{d|i}f(i/d)g(d)\\=\sum_{d=1}^ng(d)\sum_{i=1}^{n/d}f(i)\\=\sum_{d=1}^n g(d)s(n/d) i=1n(fg)(i)=i=1ndif(i/d)g(d)=d=1ng(d)i=1n/df(i)=d=1ng(d)s(n/d)

。然后其实求得 g ( 1 ) s ( n ) g(1)s(n) g(1)s(n) 就行了(因为 g g g 是一个积性函数,所以其实就是 s ( n ) s(n) s(n))。

显然 g ( 1 ) s ( n ) = ∑ i = 1 n ( f ∗ g ) ( i ) − ∑ d = 2 n g ( d ) s ( n / d ) g(1)s(n)=\sum_{i=1}^n(f*g)(i)-\sum_{d=2}^n g(d)s(n/d) g(1)s(n)=i=1n(fg)(i)d=2ng(d)s(n/d),剩下的可以递归进去。

按照朴素的算法去计算,可以 O ( n 3 / 4 ) O(n^{3/4}) O(n3/4)

如果预处理前 n 2 / 3 n^{2/3} n2/3 个可以做到 O ( n 2 / 3 ) O(n^{2/3}) O(n2/3)

0x52 莫比乌斯函数前缀和

我们待求的 s s s 就是 ∑ i = 1 n μ ( i ) \sum_{i=1}^n \mu(i) i=1nμ(i) 了。

因为 e = μ ∗ I e=\mu* I e=μI,我们可以以 I I I 作为 g g g 函数,然后 s ( n ) = 1 − ∑ d = 2 n s ( n / d ) s(n)=1-\sum_{d=2}^n s(n/d) s(n)=1d=2ns(n/d)

右半部分显然可以整除分块。

然后可以线性筛出之前 n 2 / 3 n^{2/3} n2/3 项,就是 O ( n 2 / 3 ) O(n^{2/3}) O(n2/3) 的复杂度了(可以使用 map 之类的数据结构记录)。

0x53 欧拉函数前缀和

因为 φ ∗ I = i d \varphi*I=id φI=id,所以我们把 I I I 作为 g g g 函数,然后代入上面的式子, s ( n ) = ∑ i = 1 n i d ( i ) − ∑ d = 2 n s ( n / d ) s(n)=\sum_{i=1}^n id(i)-\sum_{d=2}^ns(n/d) s(n)=i=1nid(i)d=2ns(n/d)

左半部分其实就是 ( 1 + n ) n / 2 (1+n)n/2 (1+n)n/2。按照莫比乌斯前缀和的套路套进去,依旧可以做到 O ( n 2 / 3 ) O(n^{2/3}) O(n2/3)

0x54 【模板】杜教筛 代码实现

整除分块的变量需要使用 LL。两个不同的杜教筛可以封装成为一个东西。记忆化可以使用 map

#include
using namespace std;typedef int I;typedef long long LL;const I inf=0x3f3f3f3f;I FL,CH;template<typename T>bool in(T&a){for(FL=1;!isdigit(CH)&&CH!=EOF;CH=getchar())if(CH=='-')FL=-1;for(a=0;isdigit(CH);CH=getchar())a=a*10+CH-'0';return a*=FL,CH==EOF?0:1;}template<typename T,typename...Args>I in(T&a,Args&...args){return in(a)+in(args...);}
const I NB=2e6+10,lim=2e6;
struct sieve{
	map<LL,LL>s;
	bool type;
	I dep;
	LL su[NB];//for s1:phi for s2:mu
	LL sum(LL x){
		if(x==1)return 1;
		if(x<=lim)return su[x];
		if(s.count(x))return s[x];
		LL ans=0;
		if(type==1)ans=1;
		else ans=(x%2==0)?(x/2)*(x+1):((x+1)/2)*x;
		for(LL l=2,r=0;l<=x;l=r+1){
			r=x/(x/l);
			ans-=(r-l+1)*sum(x/l);}
		return s[x]=ans;}
}S1,S2;
bitset<NB>p;I pr[200001],pl;
void pres(){
	for(I i=2;i<=lim;++i){
		if(!p[i])pr[++pl]=i,S1.su[i]=i-1,S2.su[i]=-1;
		for(I j=1;j<=pl&&1ll*pr[j]*i<=lim;++j){
			p[pr[j]*i]=1;
			if(i%pr[j]==0){
				S1.su[i*pr[j]]=S1.su[i]*pr[j];
				S2.su[i*pr[j]]=0;break;}
			S1.su[i*pr[j]]=S1.su[i]*(pr[j]-1);
			S2.su[i*pr[j]]=-S2.su[i];
		}
	}S1.su[1]=S2.su[1]=1;
	for(I i=2;i<=lim;++i)S1.su[i]+=S1.su[i-1],S2.su[i]+=S2.su[i-1];}
int main(){
	S2.type=1;
	pres();
	I T,n;in(T);
	while(T--){
		in(n);
		printf("%lld %lld\n",S1.sum(n),S2.sum(n));}
	return 0;
}

0x55 回到例题

s ( x ) s(x) s(x) 表示欧拉函数的前缀和,这次因为要杜教筛就算上 1 1 1 了。

答案其实就是求 ∑ g = 1 n g × ( s ( n / g ) − 1 ) \sum_{g=1}^n g\times (s(n/g)-1) g=1ng×(s(n/g)1)。这个减一不用管它,丢到末尾处理一下就行了。

我直接套进去查询,表面上是 O ( T n 7 / 6 + n 2 / 3 ) O(Tn^{7/6}+n^{2/3}) O(Tn7/6+n2/3) 的。 实际上是 O ( T n 2 / 3 ) O(Tn^{2/3}) O(Tn2/3) 的~~(目前我不会证明)~~。

我的直觉:为什么是 O ( T n 2 / 3 ) O(Tn^{2/3}) O(Tn2/3) 的呢?因为这个根号求解的过程也像是杜教筛的流程,其实求解最终答案的复杂度就和求解 s ( n ) s(n) s(n) 是一个数量级的。(一个求解 s ( n ) s(n) s(n) 也要递归下其儿子)而且很多答案已经记忆化过了,不会超过 O ( n 2 / 3 ) O(n^{2/3}) O(n2/3) 次运算。可能有点卡常。

然而时限给了 20 s 20s 20s 空间 1.5 G 1.5G 1.5G,即使是 O ( T n 2 / 3 ) O(Tn^{2/3}) O(Tn2/3) 的理论上也能跑过去。

而且这玩意可能也跑不到 O ( T n 2 / 3 ) O(Tn^{2/3}) O(Tn2/3) 级别那么大。事实证明 13 13 13 秒就能跑过去了。

下列是例题代码:

#pragma GCC optimize(3,"Ofast","inline")
#include
using namespace std;typedef unsigned long long LL;
const LL lim=4e7;
bitset<lim+10>p;
vector<LL>pr;
LL phi[lim+10],T,N;
map<LL,LL>ms;
LL sum(LL n){
	return (n&1)?(n+1)/2*n:n/2*(n+1);}
LL ss(LL x){//杜教筛
	if(x<=lim)return phi[x];
	if(ms.count(x))return ms[x];
	LL ans=sum(x);
	for(LL l=2,r=0,op;l<=x;l=r+1){
		r=x/(op=x/l);
		ans-=(r-l+1)*ss(op);}
	return ms[x]=ans,ans;}
LL su(LL n){LL ans=0;
	for(LL l=1,r=0,op;l<=n;l=r+1){
		r=n/(op=n/l);
		ans+=(sum(r)-sum(l-1))*ss(op);
	}return ans-sum(n);}
int main(){
	for(LL i=2;i<=lim;++i){
		if(!p[i])pr.push_back(i),phi[i]=i-1;
		for(LL j:pr){if(i*j>lim)break;
			p[i*j]=1;
			if(i%j==0){
				phi[i*j]=phi[i]*j;break;}
			phi[i*j]=phi[i]*(j-1);}}
	phi[1]=1;for(LL i=2;i<=lim;++i)phi[i]+=phi[i-1];
	scanf("%llu",&T);while(T--){
		scanf("%llu",&N);
		printf("%llu\n",su(N));}
	return 0;
}

0x5F 有点难度的作业题

P3768 简单的数学题

笔者注:这道题目我推导了许久,需要各种熟练的数论套路,才能通过。

0x60 探索更多积性函数

前面我们已经介绍过 I ( n ) , e ( n ) , i d ( n ) , μ ( n ) , φ ( n ) I(n),e(n),id(n),\mu(n),\varphi(n) I(n),e(n),id(n),μ(n),φ(n) 了,这次再来介绍几个小伙伴给我们认识。

d ( n ) d(n) d(n):我们 n n n 的约数个数。而 d ( n ) d(n) d(n) 显然等于 I ( n ) ∗ I ( n ) I(n)*I(n) I(n)I(n)

σ ( n ) σ(n) σ(n):我们 n n n 的约数之和。显然, σ ( n ) = i d ( n ) ∗ I ( n ) σ(n)=id(n)* I(n) σ(n)=id(n)I(n)。同理,可得 σ k ( n ) = i d k ( n ) ∗ I ( n ) σ^k(n)=id^k(n)*I(n) σk(n)=idk(n)I(n)

积性函数之间的卷积关系如下图所示。第 i i i 行第 j j j 列的函数,等于第 i i i 行的函数乘上第 j j j 列的函数。

(这个表格我不会填,大佬能教教我吗)

e e e I I I i d id id μ \mu μ φ \varphi φ d d d σ σ σ
e e e e ∗ e = e e*e=e ee=e e ∗ I = I e*I=I eI=I e ∗ i d = i d e*id=id eid=id e ∗ μ = μ e*\mu=\mu eμ=μ e ∗ φ = φ e*\varphi=\varphi eφ=φ e ∗ d = d e*d=d ed=d e ∗ σ = σ e*σ=σ eσ=σ
I I I I ∗ e = I I*e=I Ie=I I ∗ I = d I*I=d II=d I ∗ i d = σ I*id=σ Iid=σ I ∗ μ = e I*\mu=e Iμ=e I ∗ φ = i d I*\varphi=id Iφ=id
i d id id i d ∗ e = i d id*e=id ide=id i d ∗ I = σ id*I=σ idI=σ ? i d ∗ μ = φ id*\mu=\varphi idμ=φ
μ \mu μ μ ∗ e = μ \mu*e=\mu μe=μ μ ∗ I = e \mu*I=e μI=e μ ∗ i d = φ \mu*id=\varphi μid=φ d ∗ μ = I d*\mu=I dμ=I
φ \varphi φ φ ∗ e = φ \varphi*e=\varphi φe=φ ?
d d d d ∗ e = d d*e=d de=d d ∗ μ = I d*\mu=I dμ=I
σ σ σ σ ∗ e = σ σ*e=σ σe=σ

0x61 关于 d d d 的一些性质

d = I ∗ I d=I*I d=II,显然,它是一个积性函数,满足 d ( i j ) = d ( i ) d ( j ) d(ij)=d(i)d(j) d(ij)=d(i)d(j)(其中 i i i j j j 互质)。

它的定义式也是 ∑ d ∣ i I ( d ) \sum_{d|i}I(d) diI(d)

根据正整数唯一分解定理,如果 n n n 被分解成了 ∏ i = 1 m p i k i \prod_{i=1}^m p_i^{k_i} i=1mpiki,那么其 d d d 值就是 ∏ i = 1 m ( k i + 1 ) \prod_{i=1}^m (k_i+1) i=1m(ki+1)

使用乘法原理可以证明,不再赘述。

另外,如果有一个 x x x 一个 y y y,想要求 d ( x y ) d(xy) d(xy),那么令 g = ( x , y ) g=(x,y) g=(x,y),从而得到 x / g x/g x/g y / g y/g y/g g g g 两两互质。

所以 d ( x y ) = d ( x / g ) d ( y / g ) d ( g ) d(xy)=d(x/g)d(y/g)d(g) d(xy)=d(x/g)d(y/g)d(g)

0x7F 总结

通过今天的学习,我们学到了:

  • 狄利克雷卷积,及其衍生和拓展
  • 积性函数的定义
  • 一些基础积性函数, I , e , i d I,e,id I,e,id
  • 一些高级积性函数及其应用(比如 φ , μ \varphi,\mu φ,μ
  • 一些其他的积性函数,比如 d d d σ σ σ 的定义。
  • 杜教筛,快速对积性函数求和的方法。
  • 一些把 gcd ⁡ \gcd gcd 和互质转化为莫比乌斯函数的套路……

美中不足的是,还有许多知识点没有系统性去处理。在日后的版本之中,可能会加以改进。

  • 对莫比乌斯、欧拉函数所提供的习题例题数量有限,没有更具思维含量的好题。
  • d d d 的运用和 σ σ σ 的运用没有展开来细谈,没有对该方面题目加深了解。
  • 该文章在写作之初,笔者的初心是要给新手提供更加入门、简洁易懂的积性函数入门资料的,但是后面部分的风格和前面部分迥乎不同,这不好。可能在日后,会作修改。
  • 但愿以后不要有《积性函数及其高级应用》这篇文章,又得花费很长时间去整理、打通了。

另外,再度感谢 command_block 和 一部分洛谷题解 和 OI-wiki 提供了我入门积性函数的资料与例题,十分感激他们的付出。

今天的课就上到这里,最后我送大家一句话:

“学习?学个屁!”

你可能感兴趣的:(学习,算法,数学)