数论学习笔记

质数筛法

Eratosthenes筛选法

顾名思义就是数学家 Eratosthenes 发明的筛法,简称为埃氏筛。

基本思想

质数的倍数一定不是质数。

实现方法

用一个长度为 N + 1 N+1 N+1 的数组保存信息, 0 0 0 表示质数, 1 1 1 表示合数。先假设所有的数都是质数(初始化为 0 0 0),从小到大枚举每一个质数 x x x,把 x x x 的倍数都标记为非质数(置为 1 1 1)。

如何枚举质数 x x x 呢?从小到大扫描到 x x x 时,若 x x x 未被标记,则它不能被 2 ∼ x − 1 2\sim x-1 2x1 之间的任何数整除,则 x x x 为质数。

举个例子:

2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , ⋯ ⇓ 2 , 3 , 5 , 7 , 11 , ⋯ ⇓ ⋯ \begin{aligned} &2,3,4,5,6,7,8,9,10,11,12,\cdots\\ &\Downarrow\\ &2,3,5,7,11,\cdots\\ &\Downarrow\\ &\cdots \end{aligned} 2,3,4,5,6,7,8,9,10,11,12,2,3,5,7,11,

可以发现,存在重复标记的耗时行为。实际上,小于 x 2 x^2 x2 x x x 的倍数在扫描更小的数时就已经被标记过了。因此,可以优化一下,对于每个 x x x,把大于等于 x 2 x^2 x2 x x x 的倍数标记为合数即可。

代码如下:

void primes(int n)
{
    memset(v,0,sizeof(v));
    for(int i=2;i<=n;i++)
    {
        if(v[i]) continue;
        cout<<i<<endl;
        for(int j=i;j<=n/i;j++) v[i*j]=1;
    }
}

算法的时间复杂度为 O ( n log ⁡ log ⁡ n ) O(n\log\log n) O(nloglogn),效率非常接近于线性。时间复杂度的证明非常复杂,本蒟蒻也不太会,所以不证了

线性筛法

即使在优化后,埃氏筛仍然会重复标记合数。举个栗子, 12 12 12 既会被 2 2 2 标记又会被 3 3 3 标记,其根本原因是算法不能确定唯一的产生 12 12 12 的方式。

所以,我们只要保证合数被它的最小质因数筛去就好啦!时间复杂度为 O ( n ) O(n) O(n)

代码如下:

int v[maxn],prime[maxn];
void primes(int n)
{
    memset(v,0,sizeof(v));//存储最小质因子
    int m=0;//质数数量
    for(int i=2;i<=n;i++)
    {
        if(v[i]==0)
            v[i]=i,prime[++m]=i;
        for(int j=1;j<=m;j++)
        {
            //i有比prime[j]更小的质因子或者要筛的数超出n的范围
            if(prime[j]>v[i]||prime[j]*i>n) break;
            v[i*prime[j]]=prime[j];
        }
    }
    for(int i=1;i<=m;i++)
        cout<<prime[i]<<endl;
}

费马小定理、欧拉定理

费马小定理

如果 p p p 是一个质数,而整数 a a a 不是 p p p 的倍数,则有 a p − 1 = 1 ( m o d p ) a^{p-1}=1\pmod p ap1=1(modp)

一般情况: a p = a ( m o d p ) a^p=a \pmod p ap=a(modp)

欧拉定理

欧拉函数

对正整数 n n n,欧拉函数是小于等于 n n n 的数中与 n n n 互质的数的数目。

引理 1
  1. 如果 n n n 为某一个素数 p p p,则: φ ( p ) = p − 1 \varphi(p)=p-1 φ(p)=p1
  2. 如果 n n n 为某一个素数的 p p p 的幂次 p n p^n pn,则: φ ( p n ) = ( p − 1 ) × p n − 1 \varphi(p^n)=(p-1) \times p^{n-1} φ(pn)=(p1)×pn1
  3. 如果 n n n 为任意两个互质的数 a , b a,b a,b 的积,则: φ ( a × b ) = φ ( a ) φ ( b ) \varphi(a\times b)=\varphi(a)\varphi(b) φ(a×b)=φ(a)φ(b)
引理 2

n = p 1 a 1 × p 2 a 2 × ⋅ ⋅ ⋅ × p k a k n=p_1^{a_1}\times p_2^{a_2}\times···\times p_k^{a_k} n=p1a1×p2a2×⋅⋅⋅×pkak 为正整数 n n n 的素数幂乘积表达式,则: φ ( n ) = n × ( 1 − 1 p 1 ) × ( 1 − 1 p 2 ) × ⋅ ⋅ ⋅ × ( 1 − 1 p k ) \varphi(n)=n\times(1-\dfrac{1}{p_1})\times(1-\dfrac{1}{p_2})\times···\times(1-\dfrac{1}{p_k}) φ(n)=n×(1p11)×(1p21)×⋅⋅⋅×(1pk1)

欧拉定理

a a a m m m 互质,则 a φ ( m ) = 1 ( m o d m ) a^{\varphi(m)}=1\pmod m aφ(m)=1(modm)

同余性质

前置芝士:费马小定理、欧拉定理

整数 a , b , c a,b,c a,b,c,自然数 m , n m,n m,n,模 m m m

  • 自反性: a ≡ b ( m o d m ) a\equiv b\pmod m ab(modm)

  • 对称性:若 a ≡ b ( m o d m ) a\equiv b\pmod m ab(modm),则 b ≡ a ( m o d m ) b\equiv a\pmod m ba(modm)

  • 传递性:若 a ≡ b ( m o d m ) , b ≡ c ( m o d m ) a\equiv b\pmod m,b\equiv c\pmod m ab(modm),bc(modm),则 a ≡ c ( m o d m ) a\equiv c\pmod m ac(modm)

  • 同加性:若 a ≡ b ( m o d m ) a\equiv b\pmod m ab(modm),则 a + c ≡ b + c ( m o d m ) a+c\equiv b+c\pmod m a+cb+c(modm)

  • 同乘性:若 a ≡ b ( m o d m ) a\equiv b\pmod m ab(modm),则 a c ≡ b c ( m o d m ) ac\equiv bc\pmod m acbc(modm)

    一般情况,若 a ≡ b ( m o d m ) , c ≡ d ( m o d m ) a\equiv b\pmod m,c\equiv d\pmod m ab(modm),cd(modm),则 a c ≡ b d ( m o d m ) ac\equiv bd\pmod m acbd(modm)

  • 同幂性:若 a ≡ b ( m o d m ) a\equiv b\pmod m ab(modm),则 a n ≡ b n ( m o d m ) a^n\equiv b^n\pmod m anbn(modm)

  • a   m o d   p = x , a   m o d   q = x a\bmod p=x,a\bmod q=x amodp=x,amodq=x p , q p,q p,q 互质,则 a   m o d   p q = x a\bmod pq=x amodpq=x

乘法逆元

定义

a x = 1 ( m o d b ) ax=1 \pmod b ax=1(modb) a , b a,b a,b 互质,则称 x x x a a a 的逆元,记为 a − 1 a^{-1} a1

作用

逆元可以在计算 t a   m o d   b \boxed{\dfrac{t}{a}\bmod b} atmodb 时,转化为 t × a − 1   m o d   b \boxed{t\times a^{-1}\bmod b} t×a1modb

求法

扩展欧几里得算法

根据逆元的定义,可转化为 a x + b y = 1 ax+by=1 ax+by=1,用扩展欧几里得算法求解。时间复杂度 O ( log ⁡ b ) O(\log b) O(logb)

友情赠送代码:

void exgcd(int a,int b,int c,int &x,int &y)
{
    if(a==0)
    {
        x=0;y=c/b;
        return;
    }
    else
    {
        int tx,ty;
        exgcd(b%a,a,tx,ty),x=ty-(b/a)*tx,y=tx;
        return;
    }
}
线性算法

前置芝士: 1 − 1 ≡ 1 ( m o d p ) 1^{-1}\equiv1\pmod p 111(modp)

p = k × i + r , r < i , 1 < i < p p=k\times i+r,r<i,1<i<p p=k×i+r,r<i,1<i<p,则: k × i + r ≡ 0 ( m o d p ) k\times i+r\equiv 0\pmod p k×i+r0(modp)

两边同时乘 i − 1 , r − 1 i^{-1},r^{-1} i1,r1 就会得到:

k × r − 1 + i − 1 ≡ 0 i − 1 ≡ − k × r − 1 i − 1 ≡ − [ p i ] × ( p   m o d   i ) − 1 \begin{aligned} k\times r^{-1}+i^{-1}&\equiv0\\ i^{-1}&\equiv-k\times r^{-1}\\ i^{-1}&\equiv-\left[\dfrac{p}{i}\right]\times (p\bmod i)^{-1}\\ \end{aligned} k×r1+i1i1i10k×r1[ip]×(pmodi)1

于是,就可以递归求逆元啦!代码只有一行!

inv[i]=-(p/i)*inv[p%i];

这种方法可以在 Θ ( log ⁡ 2 p ) \Theta(\log_2p) Θ(log2p)(众所周知 Θ \Theta Θ 表示时间复杂度更准确 qwq)的时间内求出单个数逆元。

线性方程

前置芝士:人人都会的辗转相除法( ∀ a , b ∈ N , b ≠ 0 , gcd ⁡ ( a , b ) = gcd ⁡ ( b , a   m o d   b ) \forall a,b\in \mathbb{N},b\neq0,\gcd(a,b)=\gcd(b,a\bmod b) a,bN,b=0,gcd(a,b)=gcd(b,amodb)

扩展欧几里得算法

定理 1

a ≠ 0 , b ≠ 0 a\neq0,b\neq0 a=0,b=0,存在整数 x 、 y x、y xy,使得 a x + b y = gcd ⁡ ( a , b ) ax+by=\gcd(a,b) ax+by=gcd(a,b)

证明

在欧几里得算法的最后一步,当 b = 0 b=0 b=0 时, gcd ⁡ ( a , b ) = a \gcd(a,b)=a gcd(a,b)=a。因为 1 × a + 0 × 0 = a 1\times a+0\times 0=a 1×a+0×0=a,所以 a x + b y = gcd ⁡ ( a , b ) ax+by=\gcd(a,b) ax+by=gcd(a,b) 有一组解为 x = 1 , y = 0 x=1,y=0 x=1,y=0

b ≠ 0 b\neq0 b=0 时,递归求 gcd ⁡ ( b , a   m o d   b ) \gcd(b,a\bmod b) gcd(b,amodb),假设存在一组整数解 x ′ , y ′ x',y' x,y,满足 b x ′ + ( a   m o d   b ) y ′ = gcd ⁡ ( b , a   m o d   b ) = gcd ⁡ ( a , b ) bx'+(a\bmod b)y'=\gcd(b,a\bmod b)=\gcd(a,b) bx+(amodb)y=gcd(b,amodb)=gcd(a,b),那么可以推出:

b x ′ + ( a − ⌊ a b ⌋ × b ) y ′ = gcd ⁡ ( a , b ) a y ′ + b ( x ′ − ⌊ a b ⌋ y ′ ) = gcd ⁡ ( a , b ) \begin{aligned} &bx'+(a-\lfloor\dfrac{a}{b}\rfloor\times b)y'=\gcd(a,b)\\ &ay'+b(x'-\lfloor\dfrac{a}{b}\rfloor y')=\gcd(a,b) \end{aligned} bx+(aba×b)y=gcd(a,b)ay+b(xbay)=gcd(a,b)

于是乎,令 x = y ′ , y = x ′ − ⌊ a b ⌋ y ′ x=y',y=x'-\lfloor\dfrac{a}{b}\rfloor y' x=y,y=xbay

代码如下:

(对于 & 取地址符的问题,如果不加,相当于把传进去的参量复制了一份进入到函数中,不会影响主函数里的那个值;如果加取地址符相当于直接把参量扔进去了)

void exgcd(int a,int b,int &g,int &x,int &y)//g是gcd(a,b)
{
    if(!b) x=1,y=0,g=a;
    else exgcd(b,a%b,g,y,x),y-=x
}
定理 2

对于不定方程 a x + b y = c ax+by=c ax+by=c,当且仅当 gcd ⁡ ( a , b ) = c \gcd(a,b)=c gcd(a,b)=c 时,方程有整数解。

莫比乌斯反演

莫比乌斯函数

前置芝士:质数筛选

定义

设正整数 N N N 按照算数基本定理分解质因数为 p 1 c 1 p 2 c 2 ⋯ p m c m p_1^{c_1}p_2^{c^2}\cdots p_m^{c_m} p1c1p2c2pmcm,定义函数

μ ( N ) = { 0 ∃ i ∈ [ 1 , m ] , c i > 1 1 m ≡ 0 ( m o d 2 ) , ∀ i ∈ [ 1 , m ] , c i = 1 − 1 m ≡ 1 ( m o d 2 ) , ∀ i ∈ [ 1 , m ] , c i = 1 \mu(N)= \begin{cases} 0&\exists i\in[1,m],c_i>1\\ 1&m\equiv0\pmod2,\forall i\in[1,m],c_i=1\\ -1&m\equiv1\pmod2,\forall i\in[1,m],c_i=1 \end{cases} μ(N)= 011i[1,m],ci>1m0(mod2),i[1,m],ci=1m1(mod2),i[1,m],ci=1

μ ( n ) \mu(n) μ(n) 即为莫比乌斯函数。

N N N 包含相等的质因子时, μ ( n ) = 0 \mu(n)=0 μ(n)=0。当 N N N 的所有质因子各不相等时,若 N N N 有偶数个质因子, μ ( N ) = 1 \mu(N)=1 μ(N)=1;若 N N N 有奇数个质因子, μ ( N ) = − 1 \mu(N)=-1 μ(N)=1

求法

若只求一项莫比乌斯函数,分解质因数即可。

若求 1 ∼ N 1\sim N 1N 的每一项莫比乌斯函数,可以使用埃氏筛。先把所以 μ \mu μ 初始化为 1 1 1。对于筛出的每一个质数 p p p,令 μ ( p ) = − 1 \mu(p)=-1 μ(p)=1,扫描 p p p 的倍数,检查 x x x 能否被 p p p 整除。若能,则令 μ ( x ) = 0 \mu(x)=0 μ(x)=0;否则,令 μ ( x ) = − μ ( x ) \mu(x)=-\mu(x) μ(x)=μ(x)

代码如下:

  • 埃氏筛

    for(int i=1;i<=n;i++) mu[i]=1,v[i]=0;
    for(int i=2;i<=n;i++)
    {
        if(v[i]) continue;
        mu[i]=-1;
        for(int j=2*i;j<=n;j+=i)
        {
            v[j]=1;
            if((j/i)%i==0) mu[j]=0;
            else mu[j]*=-1;
        }
    }
    
  • 线性筛

    for(int i=2;i<=n;++i)
    {
        if(!vis[i]) p[++tot]=i,mu[i]=-1;
        for(int j=1;j<=tot&&1ll*p[j]*i<=n;++j)
        {
            int now=i*p[j];
            vis[now]=1;
            if(i%p[j]==0) mu[now]=0;
            else {mu[now]=-mu[i];break}
        }
    }
    
性质
  1. 对任意正整数 n n n 有: ∑ d ∣ n μ ( d ) = { 1 n = 1 0 n > 1 \sum\limits_{d|n}\mu(d)=\begin{cases}1&n=1\\0&n>1\end{cases} dnμ(d)={10n=1n>1

  2. 对任意正整数 n n n 有: ∑ d ∣ n μ ( d ) d = φ ( n ) n \sum\limits_{d|n}\dfrac{\mu(d)}{d}=\dfrac{\varphi(n)}{n} dndμ(d)=nφ(n)

莫比乌斯反演

莫比乌斯反演,可以简化运算。

定理: F ( n ) F(n) F(n) f ( n ) f(n) f(n) 是定义在非负整数集合中的两个函数, F ( n ) = ∑ d ∣ n f ( d ) F(n)=\sum\limits_{d|n}f(d) F(n)=dnf(d),那么
f ( n ) = ∑ d ∣ n μ ( d ) F ( n d ) f(n)=\sum_{d|n}\mu(d)F(\dfrac{n}{d}) f(n)=dnμ(d)F(dn)

Lucas 定理

Lucas 定理主要用于解决大组合数取模的问题。注意这里的模数 p p p 不能太大,一般小于 1 0 5 10^5 105

p p p 是质数,则对于任意整数 1 ≤ m ≤ n 1\leq m\leq n 1mn,有:
C n m = C n   m o d   p m   m o d   p × C ⌊ n / p ⌋ ⌊ m / p ⌋ ( m o d p ) C_n^m=C_{n\bmod p}^{m\bmod p}\times C_{\lfloor n/p\rfloor}^{\lfloor m/p\rfloor}\pmod p Cnm=Cnmodpmmodp×Cn/pm/p(modp)
相当于把 n n n m m m 表示为 p p p 进制数,将 p p p 进制下的每一位数计算组合数相乘。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值