数论笔记

· · 个人记录

数论笔记

质数

根据质数的定义,质数只会是1和它本身的倍数。

埃氏筛的思想,就是将每个数的倍数都标记为合数。

每个合数至少存在一个质因子,因此只需要在当前数为质数的时候标记其倍数即可。

复杂度 O(nloglogn)

v[0]=v[1]=true;
for(int i=2;i<=n;i++)
    if(!v[i])
    {
        for(int j=i+i;j<=n;j+=i)
            v[j]=true;
    }

在欧拉筛中,每个数只会被其最小的质因子筛掉。

复杂度 O(n)

v[0]=v[1]=true;
phi[1]=1;
for(int i=2;i<=n;i++)
{
    if(!v[i]) prime[++cnt]=i,phi[i]=i-1;
    for(int j=1;j<=cnt&&i*prime[j]<=n;j++)
    {
        v[i*prime[j]]=true;
        if(i%prime[j]) phi[i*prime[j]]=phi[i]*(prime[j]-1);
        else
        {
            phi[i*prime[j]]=phi[i]*prime[j];
            break;
        }
        // i%prime[j]==0 即代表 i 被 prime[j] 筛过
        // i 乘上其他的质数也是 prime[j] 的倍数
        // 而每个数都只会被其最小的质因子筛掉
        // 所以此时后面的数一定会被prime[j]筛掉,可以直接break
    }
}

欧拉筛可以求积性函数的值,例如下文提到的欧拉函数。

欧拉函数,即 \varphi(n) ,表示小于等于 n 且与 n 互质的数的个数。

n = \prod \limits_{i=1}^n p_i^{k_i}p_i 为质数,则 \varphi(n) = n \times \prod \limits_{i=1}^n \frac{p_i-1}{p_i}

积性函数:函数 f(x) 为积性函数,则对于两个数 a,b,若 gcd(a,b) = 1 ,则有 f(ab) = f(a) \times f(b)

欧拉函数是积性函数。

根据这个性质,可以用欧拉筛来递推求欧拉函数的值。

对于一个数 n,如果 n 为质数,显然 \varphi(n) = n-1

如果 n 为合数,根据欧拉筛的过程, n 会被最小的质因子 p_1 筛掉。不妨设 n' = \frac{n}{p_1}

观察线性筛的过程,我们可以对 n' \bmod p_1 分类讨论:

n' \bmod p_1 = 0 ,则 n' 包含 n 的所有质因子。

此时有

\varphi(n) = n \times \prod \limits_{i=1}^n \frac{p_i-1}{p_i} = p_1 \times n' \times \prod \limits_{i=1}^n \frac{p_i-1}{p_i} = p_1 \times \varphi(n')

n' \bmod p_1 \ne 0 ,此时根据欧拉筛的性质, n'n 互质。根据欧拉函数性质,有

\varphi(n) = \varphi(p_1) \times \varphi(n') = (p_1 - 1) \times \varphi(n')

最大公约数

最大公约数:

多个数的最大公约数: $gcd(a,b,c) = gcd(gcd(a,b),c)$ 。 维护当前最大公约数 $d$ ,对于每个数更新 $d$ 即可。 最小公倍数: $lcm(a,b) = \frac{a \times b}{gcd(a,b)}$ 。 多个数的最小公倍数: $lcm(a,b,c) = lcm(lcm(a,b),c)$ 。 按照与求 $gcd$ 相同的思路更新即可。 ```cpp int gcd(int a,int b) { return b==0?a:gcd(b,a%b); } ``` - **裴蜀定理** 对于方程 $ax + by = c$ , $x,y$ 有整数解的充要条件为 $gcd(a,b) \mid c$ 。 - **扩展欧几里得(Exgcd)** 用于求方程 $ax + by = gcd(a,b)$ 的一组可行解。 设 $ax_1 + by_1 = gcd(a,b) bx_2 + (a \bmod b)y_2 = gcd(b,a \bmod b)

由欧几里得定理可知: gcd(a,b) = gcd(b,a \bmod b)

\therefore ax_1 + by_1 = bx_2 + (a \bmod b)y_2

ax_1 + by_1 = bx_2 + (a - \left\lfloor \frac{a}{b} \right \rfloor \times b)y_2

ax_1 + by_1 = ay_2 + b(x_2 - \left\lfloor \frac{a}{b} \right \rfloor y_2)

将 $x,y$不断递归求解直至$b = 0$。当 $b = 0$ 时,即 $ax = a$,此时令 $x = 1,y = 0$ 并返回,每一层代入计算 $x,y$ 即可。 ```cpp void exgcd(int a,int b,int &x,int &y) { if(b==0) { x=1; y=0; return; } exgcd(b,a%b,x,y); int k=x; x=y; y=k-a/b*y; } ``` ### 同余 - **费马小定理** 若 $p$ 为素数,$ gcd(a,p) = 1$ ,则 $a^{p-1} \equiv 1 \pmod {p}$ 。 - **欧拉定理** 若$gcd(a,m) = 1$,则 $a^{ \varphi(m) } \equiv 1 \pmod {m}$ 。 费马小定理是欧拉定理在模数为质数时的特殊形式。 - **扩展欧拉定理** $ a^{b} \equiv \begin{cases} a^{b \bmod \varphi(m)},gcd(a,m) = 1\\ a^{b}, gcd(a,m) \ne 1 , b < \varphi(m) \\ a^{b \bmod \varphi(m) + \varphi(m)},gcd(a,p) \ne 1 ,b \geqslant \varphi(m) \end{cases} \pmod {m}

形如 ax \equiv b \pmod {c} 的方程称为线性同余方程。

定理1:

方程 ax + by = cax \equiv c \pmod {b} 等价。有整数解的充要条件为 gcd(a,b) \mid c

根据该定理,可以使用exgcd求出方程 ax + by = gcd(a,b) 的一组可行解 x_0,y_0 ,然后两边同时除以 gcd(a,b),再乘 c,得到方程 acx_0/gcd(a,b) + bcy_0/gcd(a,b) = c,这样就找到了方程的一个解。

定理2:

x_0,y_0 为方程 ax + by = c 的一组解,则该方程的任意解可表示为 x = x_0 + \frac{b}{gcd(a,b)}k , y = y_0 - \frac{a}{gcd(a,b)}k, k \in Z

根据该定理,可以求出方程的所有解。令 t = b / gcd(a,b) ,则最小整数解 x = (x_0 \bmod t + t) \bmod t

排列组合

n 个不同元素中任取 m 个元素按照一定顺序排成一列,叫做从从 n 个不同元素中取出 m 个元素的一个排列。

n 个不同元素中取出 m 个元素的所有排列个数,叫做从 n 个不同元素中任取 m 个元素的排列数,即 A_{n}^{m} / P_{n}^{m}

A_{n}^{m} = \frac{n!}{(n-m)!}

特别地,当 m>n 时, A_{n}^{m} =0

n 个不同元素中任取 m 个元素组成一个集合,叫做从 n 个不同元素中取出 m 个元素的一个组合。

n 个不同元素中取出 m 个元素的所有组合个数,叫做从 n 个不同元素中取出 m 个元素的组合数,即 C_{n}^{m}

C_n^m = \frac{A_n^m}{m!} = \frac{n!}{m!(n-m)!}

特别地,当 m>n 时, C_{n}^{m} =0

组合数也常用 \dbinom{n}{m} 表示, C_n^m = \dbinom{n}{m}

组合数性质:

C_n^m = C_n^{n-m} C_n^m = \frac{n}{m}C_{n-1}^{m-1} C_n^m = C_{n-1}^m + C_{n-1}^{m-1} \sum_{i=0}^n C_n^i = 2^n

待填坑......

咕咕咕

特别鸣谢:OIWIki (提供了本文中大部分内容)