Loading [MathJax]/jax/output/CommonHTML/autoload/mtable.js

【学习笔记】OI 数学学习笔记

OI 数学学习笔记

001_ 整除

001.1_ 整除基础

001.1A 基本定义

整除与因数倍数的定义:a,bZb0a,bZb0,若存在 qZqZ,使得 a=bqa=bq,则称 bb 整除 aa, 记为 baba,此时称 aabb因数bbaa倍数.

带余除法与余数的定义:a,bZb0a,bZb0,存在唯一的 q,rZq,rZ,使得 a=bq+r,0r<|b|a=bq+r,0r<|b|,此时记 rr余数,记为 abab(无歧义 bb 可省略) 或 amodbamodb.

公因数与最大公因数的定义:a1,a2,,ana1,a2,,an 为不全为零的整数,如果存在 bZbZ,使得 dai(i=1,2,,n)dai(i=1,2,,n),则 dd 叫做 a1,a2,,ana1,a2,,an 的一个公因数. a1,a2,,ana1,a2,,an 的公因数中最大的称为最大公因数, 记作 (a1,a2,an)(a1,a2,an)gcd(a1,a2,an)gcd(a1,a2,an). 若 (a1,a2,an)=1(a1,a2,an)=1,则称 a1,a2,,ana1,a2,,an 互素.

公倍数与最小公倍数的定义:a1,a2,,ana1,a2,,an 为全不为零的整数,若 aim(1in)aim(1in),则 mm 叫做 a1,a2,,ana1,a2,,an 的一个公倍数. a1,a2,,ana1,a2,,an 的公倍数中最小的称为最小公倍数, 记作 [a1,a2,an][a1,a2,an].

素数与合数的定义:pZ, p>1pZ, p>1. 如果 pp 正因数只有 11pp,那么就称 pp素数;反之则称 pp合数.

001.1B 整除的性质

a,b,cZa,b,cZ,则

  1. cb, bacb, ba,则 caca.

  2. ba, c0ba, c0,则 bcacbcac.

  3. ca, cbca, cb,对于任意 mnZmnZ,都有 cma+nbcma+nb.

  4. ba, abba, ab,则 a=±ba=±b.

证明方法:将 a,b,ca,b,c 替换成 qq.

001.1C 余数的性质

a1,a2,bZa1,a2,bZ,则 (角括号外省略了 bb )

  1. a1+a2=a1+a2a1+a2=a1+a2 .

  2. a1a2=a1a2a1a2=a1a2 .

  3. a1a2=a1a2a1a2=a1a2 .

证明方法:将 a1,a2,ba1,a2,b 替换成 qq.

001.2_ 欧几里得算法

[定理1.2.1(欧几里得定理)] 设 a,b,ca,b,c 是不全为零的整数,若存在 qZqZ, 使得 a=bq+ca=bq+c, 则 (a,b)=(b,c)(a,b)=(b,c),即 (a+bq,b)=(a,b)(a+bq,b)=(a,b).

证明: 由 (b,c)b, (b,c)c(b,c)b, (b,c)c 可得 (b,c)bq+c(b,c)bq+c(b,c)a(b,c)a,即 (b,c)(b,c)a,ba,b 的公因数,可知 (b,c)(a,b)(b,c)(a,b), 同理由 (a,b)a, (a,b)b(a,b)a, (a,b)b 得到 (a,b)abq(a,b)abq(a,b)c(a,b)c,可以得出 (a,b)(a,b)b,cb,c 的公因数,即有 (a,b)(b,c)(a,b)(b,c),从而有 (a,b)=(b,c)(a,b)=(b,c).

001.2A 欧几里得算法

欧几里得算法又名辗转相除法,用来求解两数的最大公因数
设整数 a>0,b>0a>0,b>0. 令 r0=a,r1=br0=a,r1=b,进行带余除法得到:

r0=r1q1+r2,0<r2<r1r1=r2q2+r3,0<r3<r2rn2=rn1qn1+rn,0<rn<rn1rn1=rnqn

最后我们可以得到 (a,b)=rn.

这是由于 (a,b)=(r0,r1)=(r1,r2)==(rn1,rn)=(rn,0)=rn (由 定理1.1

001.2B欧几里得算法的代码实现

数据范围要求:若以 gcd(a, b) 为格式输入,则输入ab不应当大于 10106. 总之大可放心用.

long long gcd(long long a, long long b)
{
    if (b == 0) return a;
    else return gcd(b, a % b);
}

时间复杂度: 该算法的时间复杂度为 O(logn).

001.3_ 一次不定方程

001.3A 裴蜀定理

[定理1.3.1(裴蜀定理)] 设 a,b 是不全为零的整数,则 存在 s,tZ,使得

sa+tb=(a,b).

证明: 若 a,b 有一个为零,则显然定理成立. 首先考虑 a>0b>0 时,对进行辗转相除法的式子进行变形:

rn=rn2rn1qn1, rn1=rn3rn2qn2 可以得到

rn=rn2(rn3rn2qn2)qn1=rn2(1+qn1qn2)rn3qn1

在这里我们将 1+qn1qn2 看作常数 m,又跟据 rn2=rn4rn3qn3得到:

rn=(rn4rn3qn3)mrn3qn1=rn3(qn3mqn1)+rn4m

这样又化为了式 (1.3.2A) 的形式,以此类推,最终我们得到 rn=sr0+tr1,从而有 sa+tb=(a,b). 由于显然有 (a,b)=(a,b)=(a,b),从而 a,b 不全大于零的情况可化为上述情况,显然成立.


[定理1.3.2(定理1.3.2的推广)] 设整数 a1,a2,,an 不全为零,则存在 s1,s2,,snZ 使得

s1a1+s2a2++snan=(a1,a2,,an)


[定理1.3.3]

  1. a,b 为不全为零的整数,则 (a,b)=1s,tZ, sa+tb=1.

  2. a,b,cZ,则 (ac,bc)=(a,b)|c|. (这里根据 (1.3.2A) 式在两边乘 2 即得)

  3. dN+,则 d=(a,b)(ad,bd)=1.

  4. (a,b)=1, abcac.

  5. (a,b)=1, ac, bcabc.

  6. (a,b)=1, (a,c)=1(a,bc)=1.

001.3B 一次不定方程的解

一次不定方程的定义: 设整数 k2, a1,a2,ak,cZ,且 a1,a2,,ak 均不为零, 未知数 x1,x2,,xk 取值均为整数的方程 a1x1+a2x2++akxk=c 称为 k 元一次不定方程.

[定理1.3.4] 设 a,b,cZa,b 均不为零,d=(a,b),对于二元一次不定方程

ax+by=c

  1. 二元一次不定方程 ax+by=c 有解的充要条件是 dc.

  2. x=x0, y=y0 是该不定方程的一组解,则它的所有解可表示为:

x=x0+bdt, y=y0adt.

特别地,若 d=1,代入得到所有解都可表示为 x=x0+bt, y=y0+at.

证明

  1. 如果上述方程有整数解,显然有 (a,b)c,即 dc. 同时,由 *定理1.3.1* 可知,存在 s,tZ,使得 sa+tb=(a,b), 设 c=k(a,b), kZ,则有 ska+tkb=k(a,b)=c,此时,方程必有两解:sktk.

  2. x,y 是方程的任意一组解,有 ax+by=c,由 x0,y0 是方程的一组解,可得 ax0+by0=c,两式相减,得:

a(xx0)=b(y0y) ad(xx0)=bd(y0y)

*定理1.3.3(3)* 可知,(ad,bd)=1,又由 定理1.4.4 可得 ady0y,故而设 tZ,有 y0y=adt,即 y=y0adt,对于任意 t,都得到对应的 y,同理此时有 x=x0+bdt. 继而该方程的全部解可表示为 x=x0+bdt, y=y0adt的形式,从而得证.


[定理1.3.5(定理1.3.4的推广)]设 k 元一次不定方程

a1x1+a2x2++anxn=c

有整数解的充要条件是 dc,其中 d=(a1,a2,,an).

001.3C 拓展欧几里得算法

我们发现,裴蜀定理证明了上述方程有一组根,我们对辗转相除法进行变形,继而就可以求出二元一次不定方程的一组整数解,从而可以求出二元一次不定方程全部整数解的形式.

设整数 a>0,b>0. 要求方程 ax+by=(a,b) 的一组根,我们先考虑方程,根据 定理1.2.1 有:

bx1+(amodb)y1=(b,amodb)=(a,b)

我们将 amodb 替换为 aabb,并带入上述方程:

bx1+(aabb)y1=(a,b)ay1+bx1baby1=(a,b)ay1+b(x1aby1)=(a,b)

可以发现这个式子与原方程形式相同,我们继而令 x=y1, y=x1aby1,从而递归地进行求解. 而递归到 b=0 时,此时有 x1=1,y1=0,然后返回.

特别地,如果我们求出这个方程的解为 xy,根据*定理1.3.4及其证明(1)*,我们依次可以求出方程 ax+bx=c, (a,b)c 的一组特解为

x0=xc(a,b), y0=yc(a,b)

时间复杂度: 显然这个算法的时间复杂度与辗转相除法相同,为 O(logb).

001.3D 拓展欧几里得的代码实现

数据范围要求:若以 Exgcd(a, b) 为格式输入,则输入ab不应当大于 10106. 总之大可放心用.

#define ll long long
ll Exgcd(ll a, ll b, ll& x, ll& y)
{
    if(b == 0){
        x = 1, y = 0;
        return a;
    }
    ll d = exgcd(b, a % b, x, y);
    ll t = x;
    x = y;
    y = t - (a / b) * y;
    return d;
}

001.4_ 算术基本定理与素数筛

001.4A 算术基本定理

[定理1.5.1(算术基本定理)] 设整数 a>1,则 a 可唯一地分解为

a=p1p2pn

其中 pi(1in) 是满足 p1p2pn 的素数.

证明:这种分解的存在性是易见的,而分解的唯一性可以用反证法证明.

设整数 a>1,它的标准分解式为:

a=pα11pα22pαkk

其中整数 αi>0(1ik), p1<p2<<pk.

001.4B 分解素因数

相当多情况下需要将一个整数 n 分解成标准分解式的形式,以解决问题;其他的情况只需要得到所有 n 的素因数,也可应用分解素因数的方法.

方法:对 n 分解素因数,那么顺序枚举 2n 的数. 如果这个数 i 能整除 n,则将它加入素因数表,并使 n 不停除以 i 直到不能整除,记录次数并记入指数表.

证明:首先 23 都是素数. 首先,如果 i 是合数,那么它的质因数应当小于它,由于是顺序枚举,那么 i 的所有质因数已被枚举过,枚举过程它的质因数的过程中 n 已将 i 的所有质因数除尽,从而 i 不可能整除 n,以此类推,在素因数表中的皆为素数. 由于各个素数互质,故而 n 的所有素因数都能加入素因数表.

时间复杂度:该方法只需要枚举 2n 的数据,复杂度为 O(n).

001.4C分解素因数的代码实现

数据范围要求:若以 PrimeFactorize(N) 为格式输入,则输入N不应当大于 1015.

#define ll long long // 不开long long见祖宗
#define MAXP 1e5 + 5 // 可调整
#define MAXA 1e5 + 5 // 可调整    
ll pi[MAXP], ai[MAXA], k, N;
// pi[i]对应标准分解式的pi,ai[i]对应标准分解式的ai,k是数组下标,N是待分解的数

void PrimeFactorize(ll N)
{
    for (int i = 2; i * i <= N; i++)
        if (N % i == 0){ 
            pi[++k] = i;
            while (N % i == 0){
                N /= i;
                ai[k]++;
            }
        }
    if (N > 1) 
        pi[++k] = N, ai[k] = 1;
}

001.5_素数筛

001.4A 埃式筛

判断 n 以内的素数,较为简便的方式是枚举 1n 以内的所有数,并在枚举时将其所有不超过 n 的倍数标记掉,显然到最后未被标记的就是素数,这就是埃拉托斯特尼筛法(厄拉多塞筛法),也称埃式筛.

时间复杂度: 埃式筛的时间复杂度是 O(nloglogn). 埃式筛的时间复杂度这里不证 (其实是因为我不会doge)

001.5B埃式筛的代码实现

数据范围要求:若以 EratosthenesPrime(n) 为格式输入,则输入n不应当大于 1.5×108.

#define ll long long //不开 long long 见祖宗
#define MAXN 1e5 + 10 //可调整
#define MAXP 1e4 + 10 //可调整
ll vis[MAXN], prime[MAXP], n, p = 0;
//n即为素数筛中的n,  p是过程中素数的下标, 最后p就是小于n的素数的数量

void EratosthenesPrime(ll N)
{
    vis[1] = 1;
    for (ll i = 2; i * i <= N; i++)
        for (ll j = i, k = i * j; k <= n; j++, k = i * j)
            vis[k] = 1; //由于i的1到i - 1倍都遍历过了,所以跳过
    for (ll i = 1; i <= N; i++)
        if (!vis[i]) prime[++p] = i;
}

001.4C 线性筛

线性筛在此基础上进行了改进,保证每个数都会且仅会被其最小素因数筛到. 首先建立一个空的标记表和素数表,我们考虑每一个正整数 ai(0in),使得 ain

  1. ai 未被标记,说明它是素数,那么我们将它加入素数表中.

  2. 对于所有枚举到的正整数 ai,枚举当前素数表中的所有素数,直到这个素数 pkai 的因数. 同时标记 ai×pk.

证明: 如果 ai 是素数,那么显然它不会被标记,考虑ai为合数的情况:从步骤1中我们可以发现,由于从小到大枚举 ai,故而加入素数表的素数是单调递增的,从而在步骤2中枚举到的最后的素数 pk,是 ai 的最小素因数. 从而我们设这个正整数 ai 的标准分解式为: ai=pα11pα122pαqq,从而 p1=pk.

在枚举到 ai 之前,已经枚举过数 as=pα111pα22pαqq,这个数的最小素因数是 p1,那么在这个数 as 在遍历到 p1 的时候,就标记了 ai,这说明 ai 会被标记. 显然它不会被 at=pα11pα212pαqq 之类的数标记,这是因为 at 在遍历到最小素因数 p1 时就停止了遍历素数表,继而不会标记比它更大的素因数p2, p3. 从而 ai 会且仅会被 as 标记.

时间复杂度: 由于每个数都会且仅会被枚举和标记一次,故而总的渐进时间复杂度为 O(n).

001.5D线性筛的代码实现

数据范围要求:若以 EulerPrime(n) 为格式输入,则输入n不应当大于 5×108.

#define ll long long //不开 long long 见祖宗
#define MAXN 1e5 + 10 //可调整
#define MAXP 1e4 + 10 //可调整
ll vis[MAXN], prime[MAXP], N, p = 0;
//n即为素数筛中的n,  p是过程中素数的下标, 最后p就是小于n的素数的数量

void EulerPrime(ll N )
{
    for (ll i = 2; i <= N; i++){
        if (!vis[i]) prime[++p] = i;
        for (ll j = 1; j <= p && i * prime[j] <= N; j++){
            vis[i * prime[j]] = 1;
            if (i % prime[j] == 0) break;
        }
    }
}

002_ 同余

002.1_ 同余基础

002.1A 同余的定义

a,bZm 是一个正整数,如果用 m 分别去除 ab,所得的余数相同,则称 ab 关于模 m 同余,用符号 ab(modm) 表示;如果余数不同,那么称 ab 关于模 m 不同余,用符号 ab(modm) 表示.

C++中的负数取余:如果运算过程中需要负数 n 需要对 m 取余,那么应当写为

ll MOD(ll n, ll m)
{
    return (n % m + m) % m;
}

[同余的充要条件] 如果 ab(modm),替换成带余除法的形式,较为简单得:存在 tZ,使得 amt=bab=mt,从而 mab. 故而我们得到 ab(modm) 的充要条件是 mab.

我们易于得到:

  1. aa(modm)

  2. ab(modm)ba(modm)

  3. ab(modm), bc(modm)ac(modm)

002.1B 同余的算术性质

[定理2.1.1] 设 a,b,c,dZm 是任意正整数.

  1. 如果 ab(modm),那么 acbc(modm).

  2. 如果 ab(modm), cd(modm),那么 a+cb+d(modm).

  3. 如果 ab(modm), cd(modm),那么 acbd(modm). (注意这里只有充分性,没有必要性)

  4. 如果 ab(modm),那么对于任意正整数 n,有 anbn(modm).

我们从同余的上述基本算术基本定理容易得到

如果 ab(modm),那么对于任意整系数多项式 f(x)=rkxk++r1x+r0, riZ, 0ik,有 f(a)=f(b).

证明

  1. 如果 ab(modm),则有 mab,从而有 macbc,所以 acbc(modm).

  2. ab(modm), cd(modm) 可知 mab, mcd,所以有 m(ab)+(cd)m(a+c)(b+d),可以推出 a+cb+d(modm).

  3. 由题设可知 mab, mcd,则 mc(ab)+b(cd),即 mac+bd,从而有 acbd(modm).

  4. n1 时,结论显然成立. 假设结论对 k(1) 也成立,即 akbk(modm). 则当 n=k+1 时,又因为 ab(modm),由 3 可知 aakbbk(modm),即 ak+1bk+1(modm),从而根据数学归纳法,对于任意正整数 n,都有 anbn(modm).


[定理2.1.2] 设 a,b,c,dZm 是任意正整数.

  1. 如果 ab(modm),正整数 dm,那么 ab(modd).

  2. 如果 acbc(modm),则 ab(modm(c,m)). 特别地,如果 (c,m)=1,则 ab(modm).

证明:

  1. ab(modm)mab,又dmdabab(modd).

  2. d=(c,m), 由 acbc(modm) 知,存在 kZ,使得 acbc=km,于是有 (ac)cd=kmdmd(ab)cd. 又因为 d=(c,m),所以 (cd,md)=1,从而有 mdab,即证得 ab(modmd).

我们对于模 m 的定理还有两个,有助于解决涉及模 m 的运算问题.


[定理2.1.3]

  1. 如果 ab(modm),又 ab(modn),那么 ab(mod[m,n]).

  2. 如果 (m,n)=1,那么

{ab(modm)ab(modn)ab(modmn)

证明

  1. ab(modm)ab(modn),可得 mab, nab,可知 a,bm,n 的公倍数,从而有 [m,n]abab(mod[m,n]).

  2. 由于 (m,n)=1,所以我们有 [m,n]=mn,由1,该定理的充分性可证;显然有 mmn, nmn,从而必要性也可证得.

002.2_ 剩余系

002.2A 完全剩余系和既约剩余系

我们可以发现,Z 中的元素关于模 m 总共有 m 种余数的情况. 换言之,我们可将 Z 中的元素分成 m 个集合,每个集合中的元素都关于模 m 同余. 我们将划分出的这些集合叫做等价类.

较为简单地,我们只需要从上述 m 个集合中选取 1 个元素讨论,我们便选取 m 个元素,使其构成一个集合 S,使得 Z 中的每个元素都与且仅与 S 中的一个元素同余. 这便引出了剩余系的定义:

剩余系的定义:SZ,如果任意整数都与 S 中的正好一个元素关于模 m 同余,则称 S 是模 m 的一个完全剩余系(简称剩余系),如果 S=0,1,2,,m1 则称 S 是关于模 m标准剩余系最小非负剩余系.


[定理2.2.1] 设 S={a1,a2,,ak}Z,则 S 是模 m 的一个完全剩余系的充要条件是: k=m, aiaj(modm)(ij).

这个定理根据定义易于理解,在此不做证明.


[定理2.2.2] 设 S={a1,a2,,am} 是模 m 的一个完全剩余系,(k,m)=1,则 S={ka1+b,ka2+b,,kam+b} 也是模 m 的一个完全剩余系.

证明: 不妨假设 kai+bkaj+b(modm)(ij),则由*定理2.1.1(2)*kaikaj(modm),又因为 (k,m)=10,由*定理2.1.2(2)*可知 aiaj(modm),但根据*定理2.2.1*,这与 S 是模 m 的一个完全剩余系相矛盾,继而 kai+bkaj+b(modm)(ij),即 S 也是模 m 的完全剩余系.

既约剩余系的定义: 在模 m 的一个完全剩余系 S 中,有的数与 m 互素,与 m 互素的数构成的集合称作模 m 的一个既约剩余系.

我们设对于模 m 所划分出的等价类中的一个为 S[r]={,rm,r,r+m,r+2m},则如果 (r,m)=1 的话,根据 定理1.2.1 我们得到 (rm,m)=(r+m,m)=(r,m)=1,以此类推,该等价类中的所有元素都与 m 互素;反之,若 (r,m)1,同理该等价类中的所有元素都与 m 不互素. 由于模 m 的完全剩余系中的元素是从各个等价类中选取一个组成的,故而完全剩余系中与 m 互素的的个数根据等价类是固定的. 即既约剩余系的大小固定.

欧拉函数的定义: 据此,我们定义欧拉函数 φ(m),表示模 m 的既约剩余系的大小. 若考虑模 m 的一个标准剩余系,则 φ(m)表示不大于 m 的正整数中与 m 互素的数的个数.

显然,一个素数与所有小于它的正整数互素,设 p 为一个素数,则有 φ(p)=p1. 从而对于任意正整数 m,都有 φ(m)m1.


[定理2.2.3] 设 S={a1,a2,,ak}Z,则 Sm 的一个既约剩余系的充要条件是:

  1. k=φ(m)

  2. ij 时, aiaj(modm)

  3. 对任意 aiS,都有 (ai,m)=1.

即:任意 φ(m) 个与 m 互素且两两关于模 m 不同余的数构成模 m 的一个既约剩余系.

这个定理通过定义易于证明,其实是我不想写了.


[定理2.2.4] 设 S={a1,a2,,aφ(m)} 是模 m 的一个既约剩余系,(k,m)=1,则 S={ka1,ka2,,kaφ(m)} 也是模 m 的一个既约剩余系.

证明: 易证 kaikaj(modm),而对于任意 kaiS,因 (k,m)=1,就有 (kai,m)=(ai,m)=1,从而由*定理2.2.3*,定理得证.


002.2B 欧拉定理、费马小定理

[定理2.2.5(欧拉定理)] 设 aZm 是正整数,如果 (a,m)=1 那么

aφ(m)1(modm).

证明: 设 S={a1,a2,,aφ(m)} 是模 m 的一个既约剩余系,则由定理2.2.4S=aa1,aa2,,aaφ(m) 也是模 m 的一个既约剩余系,所以 S 中任一数必与 S 中某个数关于模 m 同余,且它们一一对应,从而在整体上看,根据定理2.1.1(3),各个集合内的元素乘积同余,即:

aφ(m)φ(m)i=1ai=φ(m)i=1(aai)φ(m)i=1ai(modm).

根据同余的充要条件,我们得到

maφ(m)φ(m)i=1aiφ(m)i=1ai    m(aφ(m)1)φ(m)i=1ai

由既约剩余系的定义可知,对所有 1iφ(m),都有 (ai,m)=1,所以 (φ(m)i=1ai, m)=1,由上式得 maφ(m)1,即 aφ(m)1(modm).


[定理2.2.6(费马小定理)] 如果 aZp 为素数,则

apa(modp).

特别地,若 pa,则

ap11(modp).

证明: 若 pa,又因 p 为素数,则 (a,p)=1,还有 φ(p)=p1,由欧拉定理,则易证 ap11(modp),同乘 a,则证有 apa(modp);若 pa,则有 apa0(modp),此时定理显然成立. .

002.3_ 乘法逆元

002.3A 线性同余方程

线性同余方程:对于 a,b,mZm>0ma,则方程 axb(modm) 称为线性同余方程的一般形式. 如果有 ax0b(modm),则称 xx0(modm) 是该同余方程的一个.

我们根据 *同余的等价形式*,事实上, axb(modm)maxb,即存在 kZ,使得 axmk=b,这里 k 的符号可以忽略,我们设 d=(a,m),继而我们将该同余方程转换为了一个一次不定方程:

axmk=b

根据 *定理1.4.1*,该方程有解的充要条件是 db,设这个方程的一组解是 x0,k0 而且它的所有解都可表示为:

x=x0+mdt, k=k0adt


[定理2.3.1] 线性同余方程 axb(modm),设 (a,m)=d,则同余方程有解的充要条件是 d|b,而且线性同余方程的解可表示为:

xx0+mdt(modm),t=0,1,,d1

证明:下面要证明该方程有 d 个解,且满足条件的 t=0,1,,d1. 事实上我们就是要从它的解的表示形式中筛出同余的各项. 不妨设 x0+mdt1x0+mdt2(modm),则根据 *定理2.1.1*可作如下变换:

x0+mdt1x0+mdt2(modm)t1t2dm0(modm)dt1t2t1t2(modd)


由于线性同余方程和一次不定方程是完全等价的,我们同样可以使用 *拓展欧几里得算法* 进行求解,代码与拓展欧几里得相同.

002.3B 乘法逆元

考虑整数域上关于模 m 的乘法运算构成了一个交换 Z,对于任意 aZ,显然有 a11aa(modm),故而 1Z 的单位元.

乘法逆元:那么相应的,根据逆元的定义,存在 xZ,使得 ax1(modm),则 x 就是 a 关于模 m乘法逆元,也记为 a1.

事实上我们发现,这个式子就是线性同余方程的特殊形式,那么同样地,x 存在逆元的充要条件是 (a,m)1,即 (a,m)=1.

乘法逆元用于求模意义下的除法:乘法逆元可以用于将除法取模转换为乘法取模,特别地,它能解决一些无法整除情形.


[定理2.3.2] 对于模 m 下存在乘法逆元的 a,我们有:

baba1(modm).

证明:我们设 bak(modm),我们有

bak(modm)bka(modm)ba1kaa1k(modm)

从而我们得证 baba1k(modm).


拓欧法:一般地,我们将求乘法逆元看作求解线性同余方程,根据上文内容,使用拓展欧几里得法即可.

费马小定理法:对于 ax1(modp),易知有 pa,如果 p 是一个素数,那么依据 *费马小定理* 我们有

ax1ap1(modp)

故我们仅需使用快速幂求出 ap2,即得到了 a 的乘法逆元.

线性法:如果需要求 1,2,,n 关于素数 p (这里保证了每个数都存在逆元)每个数的逆元,我们考虑递推实现:i1=k×j1,其中 j=pmodik=pi

线性法的证明:易知 111(modp);对于之后的数 i,我们将 pmodi 改写成带余除法的式子

ki+j=p, j<|i|ki+j0(modp)kii1j1+ji1j10(modp)kj1+i10(modp)i1kj1(modp)    

002.3C 求解乘法逆元的代码实现

求解单个数的乘法逆元:使用拓展欧几里得算法,代码参考*拓欧代码*.

求解1~n的关于模素数下的乘法逆元:时间复杂度 O(n).
数据范围要求:当以 INVn(int n) 为格式输入时,n 不应当大于 5×108.

void INVn(int n, int inv[])
{
    inv[1] = 1;
    for(int i = 2; i <= n; i++)
        inv[i] = (p - p / i) * inv[p % i] % p;
}

002.4_ 欧拉函数

002.4A 欧拉函数性质

前面我们通过剩余系对欧拉函数进行了定义,我们接下来研究它的性质.


[定理2.4.1(欧拉函数的计算式)] 我们设 m 的标准分解式为 m=pα11pα22pαkkp 为质数,则:

φ(m)=m(11p1)(11p2)(11pk)=m×pm(11p)=m×pm(p1p).

证明: 已知对于任意 pi,都有 pi, 2pi, , mpipi,共 mpi 个数与 m 不互质,我们设这些数的集合为 Pi,我们设集合 M 为小于等于 m 的正整数集,则易知

φ(m)=|M||ki=1Pk|

我们易于知道,PiPj=mpipj. 同理对于任意 tk, 1ait,都有:

|Pa1Pa2Pat|=mpai

根据 容斥原理(将会在后面的部分介绍) 和上式我们得到:

LHS=|M||ki=1Pi|=|M||Pi|+i<j|PiPj|i<j<k|PiPjPk|++(1)k1|P1P2Pk|=mmpi+i<jmpipji<j<kmpipjpk++(1)kmp1p2pk=m(11p1)(11p2)(11pk)=RHS


[定理2.4.2]

  1. 如果 p 是素数且 α1,则 φ(pα)=pαpα1.

  2. (a,b)=d,则 φ(ab)=φ(a)φ(b)dφ(d)

  3. 如果 (a,b)=1,那么 φ(ab)=φ(a)φ(b).

  4. 如果 ab,那么 φ(a)|φ(b)

证明

  1. 考虑模 pα 的完全剩余系 S=1,2,,在 S 中与 pα 不互素的仅有 p 的倍数共 pα1 个,显然模 p 的既约剩余系的个数是 pαpα1 个,从而得证.

  2. LHS=abpab(11p)=apa(11p)bpa(11p)ddp(a,b)(11p)=dφ(a)φ(b)φ(d)=RHS

  3. 显然是2的特殊形式,将 d=φ(d)=(a,b)=1 带入即可.


[定理2.4.3] 设 m 是正整数,则

d|mφ(d)=m.

证明
首先,对于素数 p, 和正整数 α1,考虑 a=pα. 易知 a 的全部因数可且仅可表示为 p0,p1,p2,,pα,根据 3.2.2(1),这些因数的欧拉函数值之和可表示为:

αβ=0φ(pβ)=φ(pα)+φ(pα1)++φ(p1)+φ(p0)=pα\cancelpα1+\cancelpα1\cancelpα2++\cancelp\cancel1+\cancel1=pα

考虑 m 的标准分解式 m=pα11pα22pαkk. 显然,任意 dm 都可表示为

ki=10βiαipβii

这里我们便可有序地枚举对于 pi,所有βi的情况,得到所有 dm. 它们的欧拉函数值之和从而可表示为

d|mφ(d)=α1β1=0α2β2=0αkβk=0φ(pβ11pβ22pβkk)

由于任意 pβii 间都两两互素,根据 定理3.2.2(3),再将式 (A) 式代入,从而有:

d|mφ(d)=α1β1=0α2β2=0αkβk=0φ(pβ11)φ(pβ22)φ(pβkk)=α1β1=0φ(pβ11)α2β2=0φ(pβ22)αkβk=0φ(pβkk)=pα11pα22pαkk=m

002.4B 线性筛求欧拉函数

如果要求多个数的欧拉函数值,观察线性筛素数的过程,我们改进并用它求欧拉函数.

方法:在线性筛素数的基础上增加以下细节:考虑 ai

  1. 如果 ai 是素数,将记录为 φ(ai)=ai1.

  2. 仿照线性筛顺序枚举素数表时,枚举到素数 pi 时,在进行标记的同时进行以下操作:

    (1). 如果 piai,则记录 φ(ai×pi)=φ(ai)×(pi1);

    (2). 如果 piai,则记录 φ(ai×pi)=φ(ai)×p1

证明:我们设 ai 的标准分解式为 ai=pα11pα22pαkk. 首先步骤1易证. 其次证明步骤2:

  1. 如果 piai 的话,由于 pi 是素数,那么它们互素,则根据 *定理2.1.2(2)* 可知:

φ(ai×pi)=φ(ai)×φ(pi)=φ(ai)×(pi1)

  1. 如果 piai 的话,则易知 piai 的最小素因数,那么被标记的 ai×piai 有同样的素因数,根据 *定理2.4.1* 易知

φ(ai×pi)=ai×pai×pi(p1p)×pi=ai×pai(p1p)×pi=φ(ai)×pi.

时间复杂度:显然,该算法与线性筛算法时间复杂度相同,为 O(n).

002.4C 线性求欧拉的代码实现

数据范围要求:如果输入格式为EulerPhi(n),则n不应当大于 5×108.

#define ll long long //不开 long long 见祖宗
#define MAXN 1e5 + 10 //可调整
#define MAXP 1e4 + 10 //可调整
#define MAXF 1e5 + 10 //可调整
ll vis[MAXN], prime[MAXP], phi[MAXF], N, p = 0;
//n即为素数筛中的n,  p是过程中素数的下标, phi[i]是i的欧拉函数

void EulerPhi(ll N)
{
    for (ll i = 2; i <= N; i++){
        if (!vis[i]) {
            prime[++p] = i;
            phi[i] = i - 1;
        }
        for (ll j = 1; j <= p && i * prime[j] <= N; j++){
            vis[i * prime[j]] = 1;
            if (i % phi[j])
                phi[i * prime[j]] = phi[i] * (prime[j] - 1);
            else {
                phi[i * prime[j]] = phi[i] * prime[j];
                break;
            }
        }
    }
}

002.4D 分解求欧拉函数及其代码

求单个数的素因数,直接在素因数分解的同时用 *定理2.2.1* 带入即可.

时间复杂度:时间复杂度显然与分解素因数相同,为 O(n).

数据范围要求:如果输入格式为SingleEuler(n),那么n不应当大于 1015.

#define ll long long // 不开long long见祖宗
ll N, ans;
// N是代求欧拉函数的变量,得到ans就是最后的结果

void SinglePhi(ll N)
{
    ans = N;
    for (int i = 2; i * i <= N; i++)
        if (N % i == 0){ 
            ans = ans / i * (i - 1); //公式中是 ans * (i - 1) / i,但先乘后除见祖宗(
            while (N % i == 0) N /= i;       
        }
    if (N > 1) 
        ans = ans / n * (n - 1);
}

002.5_ 同余方程

002.5A 中国剩余定理

我们定义一个线性同余方程组

{xa1(modm1)xa2(modm2)xak(modmk)

其中, m1,m2,,mk 两两互素,我们能够得到:

[定理2.5.1(中国剩余定理)] 定义 m=mi Mi=m/mi NiM1i(modmi),则上述方程存在唯一解:

xki=1aiMiNi(modm).

证明: 因为对 i,j 都有 (mi,mj)=1,所以 (mi,m/mi)=1(Mi,mi)=1,故逆元 Ni 总存在。所以对 j

aiMiNiajMjNj+ijaiMiNi(modmi)

由于后一项中 Mi0(modmj),故后一项为零,我们立刻得到

aiMiNiajMjNjaj×1aj(modmi)


002.5B 中国剩余定理的代码实现

复杂度瓶颈在于求解乘法逆元, 时间复杂度 O(nlogn).

long long getNi(long long p, long long q)
{
    long long x = 0, y = 0;
    exgcd(p, q, x, y);
    return x * p;
}
long long CRT(int n, int ai[], int mi[])
    long long ans = 0;
    for(int i = 1; i <= n; i++) M *= mi[i];
    for(int i = 1; i <= n; i++)
        ans = ans + (ai[i] * getNi(M / mi[i], mi[i]) % M + M) % M;
    return ans % M
}

002.5C 多项式同余方程及其定理

我们考虑一个多项式同余方程

f(x)=anxn+an1xn1++a1x1+a00(modm)

这里限定 m 为一个素数,事实上,若 m 不为素数,那么我们考虑它的标准分解式 m=pα11pα22pαkk,则

f(x)0(modm){f(x)0(modpα11)f(x)0(modpα22)f(x)0(modpαkk)


[定理2.5.2(拉格朗日定理)] 设 p 为不整除 an 的素数,则同余方程

f(x)=anxn+an1xn1++a1x1+a00(modp)

至多有 n 解.


[定理2.5.3(威尔逊定理)] p 为素数的 当且仅当

(p1)!1(modp).

证明: 先证充分性:假设 p 不是素数,则它必有小于 p 的素因数 ab,所以

(p1)!=(p1)××a×b×1(p1)××p×101(modp)

矛盾!故当 (p1)!1(modp) 时, p 为素数.

再证必要性:已知 p 是素数,由费马小定理可知 x1,2,,p1(modp) 都为方程 xp10(modm) 的解,故

xp1(x1)(x2)(x(p1))(modp)

代入 xp(modp) 即证得定理. .

003_ 莫比乌斯反演

为了进入主题 莫比乌斯反演,我们需要穿插一些离散组合数学的补充内容。

003.1 组合基础

003.1A 二项式定理

二项式系数(或者我们更熟悉的组合数)为 (nr) ,代表一个 n 元素集中大小为 r 的子集个数。

依据一些组合数学的常识,我们能够得到:

[定理3.1.1] 二项式系数的性质

  1. (nr)=n!r!(nr)!

  2. (nr)=(nnr)

  3. (帕斯卡公式)对于 k[1,n1]

(nk)=(n1k)+(n1k1)

  1. (n0)+(n1)+(n2)++(nn)=2n

解释: 对于 1,2,不作过多解释;对于 3,可以带入公式 2 ;对于 4,实质就是所有 n 元素集合的子集个数,左侧是将不同大小的子集加起来,右边可以看作子集的组合意义,即每个元素都可已选择是否放入当前子集中,根据乘法原理,子集个数就是 2n


[定理3.1.2(二项式定理)] 设 n 为正整数,则对所有 xy,有:

(x+y)n=nk=0(nk)xnkyk

证明: 展开 (x+y)n,得到 (x+y)(x+y)(x+y)。事实上,每一个形如 axnkyk 的项等同于在展开式的 n 个因式中选择 k 个外,和剩余的 nkx。则根据二项式系数的定义,该项的系数就是 (nk)


[定理3.1.3(范德蒙卷积)] 对所有正整数 n,m1,m2,有:

nk=0(m1k)(m2nk)=(m1+m2n)

证明: (m1+m2n) 相当于从大集合 m1+m2 中选 n 个人的方案,而这 n 个人中,必然有 k 个属于 m1nk 个属于 m2。所以取遍了 k 的值,也便取遍了全部取 n 个人的可能的方案。也就是左边的式子等于右边的式子。


当然,关于二项式定理还有很多有意思的公式,暂且搁置。

003.1B 容斥原理

容斥原理在前面计算欧拉函数的时候介绍过,现在我们给出一个形式化的证明。

集合相关记号约定:

  • |A|=card(A) 为集合 A 的大小(元素个数).
  • AB={xxA and xB}.
  • ¯A=SA 表示在一个全集 S(一般省略)下,A 集合的补集。
  • ni=1Ai=A1A2A3An
  • ni=1Ai=A1A2A3An
    特别地,若 A1A2An= 时,称此时 ni=1Ai无交并,记 ni=1Ai=ni=1Ai

[定理3.1.4(容斥原理)]

我们设集合 S 中的对象涉及不同的 m 个性质 P1,P2,,Pm,并设子集

Ai={xxS x  Pi }(i=1,2,,m)

我们有集合 S不具有性质 P1,P2,Pm 的任何性质的元素的集合 可表示为等式左右的表达式:

|mi=1¯Ai|=|S|i|Ai|+i<j|AiAj|i<j<k|AiAjAk|++(1)m|A1A2Am|

或者记为:

|mi=1¯Ai|=|S|+mk=1[(1)kkai<ai+1|mi=1Ai|]

事实上,这个表达与如下的表达是等价的:

集合 S具有性质 P1,P2,Pm 的所有性质的元素的集合 可表示为

|mi=1Ai|=mk=1[(1)k1kai<ai+1|mi=1Ai|]

证明: 假设某个元素具有 p1,p2,,pm 中的 k 条性质,那么不难发现他对 i|Ai| 一项的贡献为 (k1),对 i<j|AiAj| 一项的贡献为 (k2) 以此类推,同时 |S| 中每一个元素都贡献了 1=(k0)。故可以得到他对右侧整体的贡献为:

(k0)(k1)+(k2)++(1)k(kk)=ki=0(ni)(1)i=(11)k=0(二项式定理)

所以具有性质的元素在等式右边的贡献为零,由于不具有任何性质的元素不属于任何 Ai,所以只在 |S| 中贡献一,所以 (1) 得证。

由于 补集的交集等于并集的补集,故 |S||mi=1¯Ai|=|mi=1Ai| 。所以 (3) 式即得证。


错位排列问题: 错位排列是指某个集合 {1,2,,n} 中的元素排列组成的一个新排列 {a1,a2,,an} 使得任意 aiai 的排列。我们记对于一个 n 元素集合的错位排序的数目为 Dn,我们有:

[定理3.1.4(错位排序的计算式)] 对于 n1

  1. Dn=n!(111!+12!13!++(1)n1n!)

  2. Dn=(n1)(Dn1+Dn2)

证明: 第一个式子基于容斥原理,第二个式子基于组合意义。

  1. 设集合 Ai 为第 i 个元素在自己位置上的排列集合,不难发现实质就是求:

Dn=|ni=1¯Ai|=|S|+nk=1[(1)kkai<ai+1|ni=1Ai|]

右侧中括号内的求和实质就是 恰有 k 个元素在自己的位置上 的排列的个数,根据乘法原理,它等于 (nk)!(nk),所以:

Dn=n!+nk=1[(1)k(nk)!(nk)]

打开就是右侧的式子。
2. 考虑组合意义:Dn1 是数字 2 位于第一位上,第二位不是 1 的错位排序的数目;Dn2 是数字 2 位于第一位上,第二位是 1 的错位排序的数目。由于第一位上除了 1 一共 n1 种填法,所以在外面要乘上一个 n1

003.2_ 偏序关系

003.2A 偏序的基本概念

由于序理论十分复杂,这里简要介绍几个基本概念。我们首先要形式化的表达出集合中的关系。

关系的定义:X 为一个集合,X 上的关系是 X有序对 的集合 X×X的子集 R。我们把属于 R 的有序对 (a,b) 写作 abab 有关);不属于 R 的有序对 (a,b) 写作 abab 无关)。

关系的可能的性质:

  1. 如果 xXxx,则称 自反的
  2. 如果 xXxx,则称 反自反的
  3. 如果 x,yXxyyx,则称 > 对称的
  4. 如果 x,yXxyxyyx,则称 反对称的;等价地,若 xyy>≼x 同时成立,则 x=y,则称 是反对称的。
  5. 对于 x,y,zX,如果 xyyz,则x>≼z,则称 对称的

偏序的定义:如果集合 X 上的一个 偏序 是满足 自反反对称传递 的一个关系。严格偏序反自反的。此时我们称集合 X偏序集, 记为 (X,)。当 X 是一个有限集时,称其为 有限偏序集

我们可以得到,偏序集 (X,) 满足:

  1. xXxx;(自反性)
  2. 如果 x,yXxyxyyx;(反对称性)
  3. xyyx 同时成立,则 x=y;(反对称性)
  4. 对于 x,y,zX,如果 xyyz,则xz (传递性)

例如:(Z,)(具有整除关系的整数集)是一个偏序集,这是因为对 x,y,zZxxxyyxx=yxyyzxz

Hasse 图表示偏序关系: 有限偏序集都能表示为一个 DAG(有向无环图)。每一个元素都是一个点,如果满足 xy,就画一条 x 指向 y 的边。例:({1,2,3,4,5,6,7,8},) 的偏序集可以表示为一张 DAG:
Hasse图举例

极大元和极小元: 对于一个元素 xX,如果不存在 yX,使 yx,则称 x 为偏序集 (X,) 上的一个 极小元;如果不存在 yX,使 xy 则称 x 为偏序集 (X,) 上的一个 极大元

可比与不可比: 如果两个元素 x,yX 是可比的,当且仅当 xyyx ;否则称其为不可比的. 如果集合 X 中的每一对元素都是可比的,则称这个集合 X 上的偏序 全序

[定理3.2.1] 一个全序集上的所有元素总能排列成 a1,a2,,an 的形式,满足 aiai+1.

归纳地证明上述引理即可。由于全序集总能表示为上面的形式,所以它又称为 线性有序集

线性拓展: 对于一个偏序集 (X,1),如果再在 X 上定义一个偏序关系 2,使得对于 a1b 都有 foralla2b,则称偏序集 (X,2) 是偏序集 (X,1) 的一个 拓展。通俗的说,偏序集的线性在原来的偏序集上能定义出一个不改变任意两元素原有拓扑关系。特别地,若这个拓展是线性有续集,则称他为 线性拓展

[定理3.2.2] 有限偏序集总存在线性拓展。

证明: 将有限偏序集看为一个 DAG,则这个 DAG 上总能跑 拓扑排序,跑完拓扑排序得到的就是这个有限偏序集的线性拓展。

003.2B 偏序集上的链

链与反链定义: X 的一个子集,满足链上的元素两两可比。反链 满足两两不可比。事实上,如果用 Hasse 图表示的话,链能够表示为一根图上的链(这是由于偏序满足反对称性,所以不存在环,而两两元素之间总存在一条边),故链上的元素可以按照偏序关系排序。

易于有,如果 A 是一条链而 C 是一条反链: |AC|1

[定理3.2.3] 设 (X,) 为一个有限偏序集,并设 r 是最长的链,则 X 最少可以划分出 r 个反链。

以及上述定理的对偶定理:

[定理3.2.4(Dilworth定理)] 设 (X,) 为一个有限偏序集,并设 r 是最长的反链,则 X 最少可以划分出 r 个链。

003.3_ 莫比乌斯反演

003.3A 莫比乌斯反演的一般形式

This section includes more sophisticated mathematics than the other sections in this chapter.
这一节所涉及的数学比前面所涉及都更加深奥和微妙。
———— 《Introductory Combinatorics》Richar A. Brualdi

为了更好的表达偏序关系,我们定义一个在偏序集 (X,) 上的二元实值函数:

f:X×XR

使得当 xy 时,f(x,y)=0。我们记所有定义在 (X,) 上的满足上述条件的 函数的集合F(X)

接着我们定义对于两个函数 f,gF(X),他们的 卷积 函数 h=fg(注意 hF(X)) :

h(x,y)={xzyf(x,z)g(z,y),if xy,0otherwise.

我们可以将函数的 (x,y) 看作一个区间 [x,y],以所有满足 xzy 的元素 z 构成。卷积实际上就是做区间运算。

[定理3.3.1(卷积的结合律)] 对于 f,g,hF(X),卷积满足结合律:

(fg)h=f(gh)

证明: 对任意 x,yX,显然只需证明 xy 的情况(否则卷积为 0):

((fg)h)(x,y)=xz1yf(x,z1)z1z2yg(z1,z2)h(z2,y)

由于偏序集的反对称性和传递性,我们可以这样变形:

xz1yf(x,z1)z1z2yg(z1,z2)h(z2,y)=xz1z2yf(x,z1)g(z1,z2)h(z2,y)=xz1z2f(x,z1)g(z1,z2)xz2yh(z2,y)=(f(gh))(x,y)


接下来我们研究四种 F(X) 上的三种特殊的函数 1,δ,1,μ

(1)δ (克罗内克)函数: 卷积运算的 单位元,对任意 x,yX

δ(x,y):={ 1,if x=y, 0otherwise.

不难发现对于任意 fF(X),有:

δf=fδ=f

想象 δ 函数将整个卷积求和下标的 z 缩到了 y 一点,实际只有一项 f(x,y)

(2)ζ 函数: 包含偏序关系的信息。对任意 x,yX

ζ(x,y):={ 1,if xy, 0otherwise.

也有称 ζ1 的。这启示我们可以将 ζ 函数看作将区间 [x,y] 缩到了 1 上。
(ζ1)(a,b)=xzy1,实质就是区间 [x,y] 的大小。

(3)μ (莫比乌斯)函数: 卷积函数 ζ逆元

但是在定义 μ 之前,首先要证明卷积运算逆元的存在性。

[定理3.3.2] 对于任意 fF(X),总存在 gF(X),使得:

gf=δ

证明: 由于偏序集的自反性(xx),故 f(y,y)0 ,我们总能找到以下 g 的递归构造(公式中 xy 表示 xyxy):

g(x,y)=1f(y,y)xzyg(x,z)f(z,y)(xy)=1f(y,y)[(xzyg(x,z)f(z,y))g(x,y)f(y,y)](xy)=g(x,y)+xzyg(x,z)f(z,y)(xy)δ(x,y)=xzyg(x,z)f(z,y)(xy)

故我们证得 了 gf=δ.

同理也总存在 fh=δ。假定存在,依据卷积的结合律能够立刻得到:

g=gδ=g(fh)=(gf)h=δh=h

我们能够得到 ff1=f1f=δ

现在我们定义莫比乌斯函数 μ 满足:

μζ=ζμ=δ

μ 函数的性质: 对于 x,yX,我们有:

  1. xzyμ(x,z)ζ(z,y)=δ(x,y)

    或等价于

    xzyμ(x,z)=δ(x,y)

  2. xX,μ(x,x)=1

  3. (依据 定理3.3.2 的构造)μ(x,y)=xzyμ(x,z)(xy)  =xzyμ(z,y)(xy)

偏序集的直积结构: 对于两个有限偏序集 (X,1)(Y,2)。我们定义集合

X×Y={(x,y)xX, yY}

和其上的偏序关系 为:

(x,y)(x,y)  当且仅当  x1x y2y

同时 (X×Y,) 也为一个偏序集。

[定理3.3.4] 设 μ1μ2 分别为偏序集 (X,1)(Y,2) 上的莫比乌斯函数,μ 为他们的直积的莫比乌斯函数,则:

μ((x,y),(x,y))=μ1(x,x)μ2(y,y)(x,y),(x,y)X×Y

证明: 对于 (x,y)(x,y) 的情况很容易验证,所以我们只需证对于 (x,y)(x,y) 的情况。我们归纳地假设对于所有 (x,y)(u,v)(x,y)(u,v) 都正确,那么我们能够得到:

μ((x,y),(x,y))=(x,y)(u,v)(x,y)μ((u,v),(x,y))=(x,y)(u,v)(x,y)μ1(u,x)μ2(v,y)=(x1u1xμ1(u,x))(yvyμ2(v,y))+μ1(x,x)μ2(y,y)=δ1(x,x)δ2(y,y)+μ1(x,x)μ2(y,y)=μ1(x,x)μ2(y,y)


[定理3.3.3(莫比乌斯反演公式)]

对于一个有最小元的有限偏序集(以便下面的求和是有限的),我们定义其集上的两个函数 F:XRG:XR,定义:

G(x):=zxF(z)(xX)

等价于

F(x)=yxG(y)μ(y,x)(xX)

证明:

yxG(y)μ(y,x)=yxμ(y,x)zyF(z)=yxμ(y,x)zXF(z)ζ(z,y)=yxzXF(z)ζ(z,y)μ(y,x)=zXF(z)yxζ(z,y)μ(y,x)=zXF(z)zyxμ(y,x)=zXF(z)δ(z,x)=F(x)

(1) 步 —— G(x) 的定义;第 (2) 步—— ζ 函数的定义;第 (3) 步 —— μ 函数乘进去(乘法分配律);第 (4) 步 —— 求和符号换位,F(x) 提出来;第 (5) 步—— ζ 函数的性质,即 1 函数非偏序为 0 导致只能统计 zy 的情况;第 (6) 步 —— μ 函数的性质;第 (7) 步 —— δ 函数的定义,即 δ 函数导致只能统计 z=x 的情况。

这种证法也太丑陋了吧!尽管证出来了(抄的书),但是过 10 分钟就忘了,怎么办!
我们设这个有限偏序集的最小元为 c
考虑将 F(x) 看作 F 上的函数 f(c,x)G(x) 看作 F 上的函数 g(c,x)=czxf(c,z)
所以本质就是:

g=f1gμ=(f1)μ=f(1μ)=fδ=f

003.3B (子集反演)再证容斥原理

容斥原理实质是莫比乌斯反演在有限偏序集上的一个实例。

我们首先定义出这个偏序集:

(P(Xn),)

其中 P(Xn)={AiAi{1,2,3,,n}},即 Ai 是大的集合 {1,2,3,,n} 的子集,而 P(Xn) 则是这些子集的集合。 表示这个集合上的关系是这些 Ai 的包含关系。

[定理3.3.5] 在偏序集 (P(Xn),) 上,若 AB,则:

μ(A,B)=(1)|B||A|

证明: 使用数学归纳法,首先对任意 μ(A,A)=(1)0=1 成立。我们归纳假设对所有 ACB,有 μ(A,C)=(1)|C||A| 成立。记 p=|B||A|,那么有:

μ(A,B)=ACBμ(A,C)=ACB(1)|C||A|=p1k=0(1)k(pk)

最后一步是由于所有 C 集合可由 A 集合中的元素加上选取 |BA| 中的任意几个元素组成。根据二项式定理:

μ(A,B)=p1k=0(1)k(pk)=((11)p(1)p(pp))=(1)p


(定理3.1.4 容斥原理)对于 A1,A2,,AnS:

|ni=1¯Ai|=|S|+nk=1[(1)kkai<ai+1|ni=1Ai|]

我们将下标写成集合的形式,设 Xn={1,2,,n},则右侧取并集本质是取下标集合的子集。为了便于书写,将右侧 |S| 一项加入到求和中,我们规定 A=S 而且 L。我们得到:

|ni=1¯Ai|=LXn(1)|L||iLAi|

为了迎合子集反演中 μ 函数的指数要求,我们将式中 1 的指数改为 n|L|。相应地,原式变为:

|iXni¯Ai|=LXn(1)n|L||iLor i=Ai|

证明(莫比乌斯反演法): 我们简记 BK=(iKi¯Ai)(jKor j=Aj)

定义:

F(K)=|BK|,G(K)=LKF(K)

根据偏序集 (P(K),) 上的莫比乌斯反演公式,我们得到:

|BK|=F(K)=LKμ(L,K)G(L)=LK(1)|K||L|JLF(J)=LK(1)|K||L|JL|BJ|

注意到容斥原理 (1) 式是实质就是当 K=Xn 时莫比乌斯反演的等价形式,所以接下来我们只需证 (1) 式右边等于 (2) 式右边,即对于任意 LK,:

JL|BJ|=|iLor i=Ai|

引理 1(求和中枚举的集合是两两不交的): 右侧方形大并符号代表无交并(依据 003.2B 的符号约定) JL|BJ|=|JLBK|

证明:我们假设对于 M,NLMN,存在 sBMsBN

由于 MN,则一定满足存在 Ai 使得 iMiN (由于 M,N 是对称的,所以 iNiM 的情况可以省略)。根据 B 的定义,由于 sBM 所以 sAi ;由于 sBN 所以 s¯Ai

但是这是矛盾的。故假设不成立,不存在这样的 s,所以所有 BJ 是无交的。

引理 2 (上式的无交并与原等式右侧等价): iL or i=Ai=JLBJ

为了简明书写,我们将所有对于 的讨论略去,但是要时刻注意 的存在。

右边展开:iLAi=JL[(iJ¯Ai)(jJAj)]

对于右边的任意一项 BJ,注意到:

BJjJAjiLAi

每一项都包含于左边,所以他们的并也包含于左边,我们得到:

JLBJiLAi

对于 siLAi,我们设该元素 s 不属于的 Aj 的下标 j 组成的集合为 C。这里 j 不一定是 L 中的元素。或者形式化地表达:C=jsAj

所以对 s,若 jC,则 sAj。我们能够得到(这一步读者需要深入思考):

s(iC¯Ai)(jCAj)=BC

由于显然 LC,而且对于所有 s 都有属于左边则属于右边,故

iLAiJLBJ

结合 (3)(4),引理得证。

根据以上两个引理,等式得证,原定理得证.

003.3C 数论中的莫比乌斯反演

我们可以将自然数集上的整除看作一个偏序集,从而从广义的莫比乌斯反演得到 经典的莫比乌斯反演。设 Xn={1,2,3,,n},我们首先定义出这个偏序集:

(Xn,  )

右侧代表整除运算,所以 ab 当且仅当 a,bXn, ab


经典莫比乌斯函数的性质: 特殊化我们之前已推出的莫比乌斯函数性质即可。

  1. μ(a,b)=μ(1,ab)

    由上式,为了简明书写,我们之后记 μ(n)=μ(1,n)

  2. dnμ(n)=[n=1]

  3. μ(n)=mnmnμ(m)

  4. 对于 (m,n)=1,有 μ(mn)=μ(m)μ(n)

  5. μ(n)={ 1n=1 0n 含有平方因子 (1)kk 为 n 的不同素因子个数

解释: 对于1,可仿照直积的证明归纳地证明。对于 2, 3 直接代入 003.3A 中的结论即可。对于 4,这表明经典的莫比乌斯函数是一个 积性函数。对于 4, 5,我们考虑 n 的标准分解式 n=pα11pα22pαkk。根据直积的性质不难得到。


[定理3.3.6(经典的莫比乌斯反演)] 定义 F 为正整数集上的一个函数,若:

G(n)=dnF(d)

则:

F(n)=dnμ(nd)G(d)


我们在偏序集 (Xn, ) 上重新考察 各类积性函数 的性质。除了我们已知的 μ,φ,δ,ζ,我们定义

id(n):=n

[定理3.3.7] 对于任意两积性函数 f,g,满足

fg=gf

[定理3.3.8]

μζ=δidμ=φφζ=id

证明:定理2.1.3 我们得到:

id(n)=dnφ(d)

莫比乌斯反演后,右侧可以表示为卷积的形式:

φ(n)=dnid(d)μ(nd)=dnid(1,d)μ(d,n)=(idμ)(n)

两侧同时卷积 ζ,得:

φζ=idμζ=idδ=id

003.3D 求一类积性函数的代码实现

μ 函数的代码实现: 和求欧拉函数类似。复杂度 O(n)

int p[MAXN], vis[MAXN], mu[MAXN], cntp = 0;
void getMu(int n)
{
    mu[1] = 1;
    for(int i = 2; i <= n; i++){
        if(!vis[i]) p[++cntp] = i, mu[i] = -1;
        for(int j = 1; j <= cntp && i * p[j] <= n; j++){
            vis[i * p[j]] = 1;
            if(i % p[j] == 0){ mu[i * p[j]] = 0; break;}
            mu[i * p[j]] = -mu[i];
        }
    }
}

杜教筛: 用于快速求积性函数的 前缀和

我们设对于某个数论函数 f 的前缀和为 S(n)=ni=1f(i)

考虑再找一个数论函数的 g,有

ni=1(fg)(i)=ni=1dig(d)f(id)=ni=1g(i)nij=1f(j)=ni=1g(i)S(ni)=ni=2g(i)S(ni)+g(1)S(n)

所以我们得到

S(n)=ni=1(fg)(i)ni=2g(i)S(ni)g(1)

运用杜教筛的前提是:

  • 能够较快地计算 fg 的前缀和
  • 能够较快的计算 g 的单点值,后一项计算 S(ni) 可以 数论分块(见附录)
  • 不要求必须为积性函数的

例:计算 φμ 的前缀和(洛谷 P4213 【模板】杜教筛

Sφ(n)=ni=1(φζ)(i)ni=2ζ(i)S(ni)ζ(1)=ni=1id(i)ni=2ζ(i)S(ni)ζ(1)Sμ(n)=ni=1(μζ)(i)ni=2ζ(i)S(ni)ζ(1)=ni=1δ(i)ni=2ζ(i)S(ni)ζ(1)

最后我们得到:

Sφ(n)=n(n+1)2ni=2S(ni),Sμ(n)=1ni=2S(ni)

const int MAXN = 5000010;
typedef long long ll;
std::unordered_map<int, ll> sphi, smu;
// 使用线性筛对小范围优化
ll phi[MAXN + 10], mu[MAXN + 10];
int pi[MAXN], vis[MAXN], cntp;
void Euler()
{
    phi[1] = mu[1] = 1;
    for(ll i = 2; i <= MAXN; i++){
        if(!vis[i]){
            pi[++cntp] = i;
            phi[i] = i - 1, mu[i] = -1;
        }
        for(ll j = 1; j <= cntp && i * pi[j] <= MAXN; j++){
            vis[i * pi[j]] = 1;
            if(i % pi[j]) {
                phi[i * pi[j]] = phi[i] * (pi[j] - 1);
                mu[i * pi[j]] = -mu[i];
            }
            else{
                phi[i * pi[j]] = phi[i] * pi[j];
                mu[i * pi[j]] = 0;
                break;
            }
        }
    }
    for(int i = 2; i <= MAXN; i++) {
        phi[i] += phi[i - 1];
        mu[i] += mu[i - 1];
    }
}
ll solvPHI(int n)
{
    if(n < MAXN) return phi[n];
    if(sphi[n]) return sphi[n];
    ll ret = 1ll * n * (n + 1ll) / 2ll;
    for(ll l = 2, r; l <= n; l = r + 1){
        r = n / (n / l);
        ret -= (r - l + 1ll) * solvPHI(n / l);
    }
    sphi[n] = ret;
    return sphi[n] = ret;
}
ll solvMU(ll n)
{
    if(n < MAXN) return mu[n];
    if(smu[n]) return smu[n];
    ll ret = 1;
    for(ll l = 2, r; l <= n; l = r + 1){
        r = n / (n / l);
        ret -= (r - l + 1ll) * solvMU(n / l);
    }
    smu[n] = ret;
    return ret;
}

00X_ 附录:相关概念与定理

00X.1 数论分块

数论分块旨在解决形如 ni=1f(i)ni 的快速求和问题。我们可以将所有 nk 相同的分到一个块中,在每块中对 f(x) 的求和就能够使用前缀和预处理出来,时间复杂度就是块的个数 O(n) (稍后证明)。


引理1(分母换为标准形式 i):

nkd=nkd

引理1的证明: 注意到 n=nkk+r (r<k<kd), 我们有:

LHS=nkk+rkd=nkd+rkd=RHS    

引理2(分块的端点): 值等于 nk 的块的右边界为 nnk

引理2的证明: 我们设值等于 nk 的块的右端点为 r,则显然有 rk,即 nrnk,故 r 只需满足 nrnk,这里我们有:

nrnrnknrnkrnnk

这里由于 r 是整数,故而 rnnk 成立。不难验证端点处成立。

引理3(分块的时间复杂度): 形如 nk,kN 的数论分块的块数为 O(n)

引理3的证明: 对于 kn,块数不超过 n;对于 kn,由于 nknn=n,所以块数不超过取值数也就不超过 n,总的块数不超过 2n=O(n) 


如果数论分块求和形如多维的(右侧中的求积可以替换成任意包含多个不同下取整的运算符)

ni=1(f(i)mj=1aji)

那么所有下取整的值相同的才能放到一块中,即每个块的右端点为 mminj=1{ajaji}


数论分块的代码: 时间复杂度 O(n)

long long Sum(long long n)
{
    long long ans = 0;
    long long  l = 1, r;
    while(l <= n){
        r = n / (n / l);
        ans += (f[r] - f[l - 1]) * (n / l); // 这里 f[i] 代表函数前缀和
        l = r + 1;
    }
    return ans;
}

00X.2 群论相关概念

:对于一个非空集合 G,和一个运算 ,如果满足:

  1. 任意 a,bG,都有 abG

  2. 任意 a,b,cG,都有 a(bc)=(ab)c,即群的结合律

  3. 存在 eG,使得对任意 aG,都有 ae=ea=a,并称 e 是群 G单位元

  4. 对于任意 aG,存在 bG,使得 ab=ba=e,并称 ba逆元,记为a1.

则称 (G,) 是一个,表示该群和运算 ab 时,通常省略运算 ,记为Gab.

对于一个群 GaG,我们一般将 aaa 简记为 an.

群的阶:对于一个群 G,如果集合 G 的大小 |G| 是有限的,则称它为有限群,反之则称他为无限群. 对于有限群 G|G| 称为群 G

交换群:对于一个群 G,如果对于任意 a,bG,都有 ab=ba,则称这个群为 Abel交换群. 通常交换群的运算用 + 表示,也将 an 记为 na.

posted @   anjack_511  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示