算法学习笔记:数论基础
f_K_e1207
·
2024-12-11 20:52:26
·
算法·理论
本文大部分内容参照进阶指南,其中例题参考部分题解,加上了一些自己的理解。
质数
定义
若一个整数 n>1 只能被 n 或 1 整除,则称该整数为质数,否则为合数。质数在整个自然数集合中分布较稀疏,对于一个足够大的整数 N ,大约每 \ln{N} 个数中有一个质数。
质数的判定
试除法作为入门级内容不再赘述,扫描 [2,\sqrt N] 之间的整数试除即可。
质数的筛选
埃氏筛与线性筛都是求解 [2,N] 之间质数的高效算法,基本思想都是扫描 [2,N] 之间的整数,并且向上标记这些整数的倍数为合数。但是埃氏筛会重复标记合数,因此时间复杂度为 \mathcal O(N\log{\log{N}}) ,这里着重讲更优的线性欧拉筛。
欧拉筛是通过确定一个合数的唯一分解方式,避免合数被重复标记,从而达到线性复杂度。具体实现方法是先把 [2,n] 之内的所有数都标记为质数,然后从 [2,n] 枚举 i ,如果 i 没有被之前的数标记为合数,则 i 是质数,可以用来更新后面的合数。枚举已经筛出来的质数 p_j(1\le j\le cnt) ,标记 i\times p_j 为合数,如果 i 是 p_j 的倍数时退出循环。
过程比较简单,因此看起来比较莫名其妙,所以在这里给出证明。首先证明其正确性。假设合数 a 的最小质因数为 p ,则设 a=p\times b ,显然 b<a ,因为 p 是 a 的最小质因数,所以 b 的最小质因数必然不小于 p 。在整个算法过程中,b 先被 i 枚举到,然后在内层循环中找到 p ,a 就被 p\times b 标记为合数了,即使 p 也是 b 的因数,也会在标记后再退出循环。接下来证明其复杂度为线性,即每个合数只被标记一次,运用反证法。对于上述假设的 a=p\times b ,如果存在 a=p'c 也将 a 标记,则若 c>b ,说明 p'<p , p 是最小质因数的假设矛盾;若 c<b ,说明 p'>p ,则 p 是 c 的质因数,且显然 p\times c<a ,根据算法流程,内层循环在还没有枚举到 c 的时候就会退出循环。
贴个代码:
void euler()
{
for (int i=2;i<=n;i++)
isprime[i]=1;
for (int i=2;i<=n;i++)
{
if (isprime[i]) prime[++cnt]=i;
for (int j=1;j<=cnt&&i*prime[j]<=n;j++)
{
isprime[i*prime[j]]=0;
if (i%prime[j]==0) break;//维持线性复杂度的关键
}
}
}
质因数分解
算数基本定理
任何一个大于一的正整数都能唯一分解为有限个质数的乘积,即:
N=p_1^{c_1}p_2^{c_2}\cdots p_m^{c_m}
其中 c_i 都是整数,p_i 都是质数,且满足 p_1<p_2<\cdots<p_m 。由于是基本定理,所以不给出证明。感性理解,如果 N 的一个因数是合数,就可以把这个因数分解为其因数的乘积的形式,如果因数的因数还是合数,还可以再分解。通过这种类似于递归的分解,最终会得到一个全部为质数的整数分解形式。
结合质数判定的试除法和质数筛选的埃氏筛法,可以通过扫描 [2,\lceil \sqrt N \rceil] 的每一个数 d ,若 d 能整除 N ,则从 N 中除去所有的因数 d ,同时累计除去 d 的个数,这个思路和其实现还是比较显然的。
贴个代码:
void divide(int n)
{
m=0;
for (int i=2;i*i<=n;i++)
{
if (n%i==0)
{
p[++m]=i;
c[m]=0;
}
while (n%i==0)
{
n/=i;
c[m]++;
}
}
if (n>1)//特判,如果最后剩下的n还是质数,则要再进行一次分解
{
p[++m]=n;
c[m]++;
}
}
约数
定义
设 d,n 为给定整数,那么一定存在唯一的一对整数 q,r ,满足 n=qd+r,\ 0\le r<|a| ,若此时 r=0 ,即 d 能整除 n ,则称 d 是 n 的约数,记为 d\mid n 。
此处需要分清因数与约数的区别,因数是在数的乘积关系下定义的,不一定是整数;约数是对于两个自然数的整除关系而言的,只能是自然数。
算数基本定理的推论
在算数基本定理中,若正整数满足上文中的条件,则 N 的正约数集合可以写作:
\{p_1^{b_1}p_2^{b_2}\cdots p_m^{b_m}\}
其中 0\le b_i\le c_i 。
$$
(c_1+1)\times(c_2+1)\times\cdots\times(c_m+1)=\prod_{i=1}^{m}(c_i+1)
$$
$N$ 的所有正约数的和为:
$$
(1+p_1+p_1^2+\cdots+p_1^{c_1})\times\cdots\times(1+p_m+p_m^2+\cdots+p_m^{c_m})=\prod_{i=1}^{m}(\sum_{j=0}^{c_i}(p_i)^j)
$$
#### 求 $N$ 的正约数集合——试除法
若 $d\le\sqrt N$ 是 $N$ 的约数,则 $\frac{N}{d}\le\sqrt N$ 也是 $N$ 的约数。如果 $N$ 不是完全平方数,约数总是成对出现的,否则 $\sqrt N$ 会单独出现。
因此,可以类比质数的判定中的试除法,扫描 $[1,\sqrt N]$,尝试 $d$ 能否整除 $N$,若能,则 $\frac{N}{d}$ 也是 $N$ 的约数,时间复杂度为 $\mathcal O(\sqrt N)$,比较简单,也不贴代码了。
#### 试除法的推论
设 $d(n)$ 为 $n$ 的约数个数,则 $d(n)=\mathcal O(\sqrt{n})$,这是比较显然的。
#### 求 $1\sim N$ 每个数的正约数集合——倍数法
若用试除法分别求解 $1\sim N$ 每个数的正约数集合,时间复杂度为 $\mathcal O(N\sqrt N)$ 。效率不够高,可以反过来考虑,对于每个数 $d$ ,$1\sim N$ 中以 $d$ 为约数的数就是 $d,2d,3d,\lfloor \frac{N}{d}\rfloor\times d$ 。
贴个代码:
~~~cpp
for (int i=1;i<=n;i++)
for (int j=1;j<=n/i;j++)
factor[i*j].push_back(i);//此处使用vector
~~~
上述算法的时间复杂度为 $\mathcal O(\sum_{i=1}^{N}\frac{N}{i})=\mathcal O(N\sum_{i=1}^{N}\frac{1}{i})=\mathcal O(N\log N)$,需要注意的是,此处 $\log$ 的含义是 $\ln$ ,许多数学相关的算法的时间复杂度中的 $\log$ 都是如此。
::::info[调和级数!]{open}
提供一个调和级数上界的简证。
已知 $\forall k\in[2^m,2^{m+1}),\frac{1}{k}\le\frac{1}{2^m}$,按照 $2$ 的幂次分长度为 $2^m$ 的组,最终可以得到:
$$
\begin{aligned}
\sum_{k=1}^N\frac1k&=1+\frac12+\frac13+\frac14 +\frac15+\frac16+\frac17+\frac18+\cdots+\frac1N\\
&\le1+\frac12+\frac12+\frac14+\frac14+\frac14+\frac14+\frac18+\cdots+\frac1{2^{\lfloor\log_2 N\rfloor}}\\
&\le1+1+1+\cdots+1\\
&=\lfloor\log_2N\rfloor+1\\
&=\mathcal O(\log N)
\end{aligned}
$$
::::
#### 倍数法的推论
$1\sim N$ 每个数约数个数的总和大约为 $N\ln N$。
### 例题:[P1463 反素数](https://www.luogu.com.cn/problem/P1463)
>设给定正整数 $x$ 的约数个数为 $g(x)$,定义满足 $\forall0<i<x,g(x)>g(i)$ 的 $x$ 为反素数,求小于等于 $N(1\le N\le 2\times10^9)$ 的最大反素数。
:::success[解法:]
本题看似复杂,无从下手,~~其实打表就可以了~~。我们先思考题目给出的新定义,根据数学直觉,约数个数少的数总体会更小,所以我们先考虑 $1 \sim N$ 中约数个数最多的数,设其中最小的数为 $m$,因此有 $\forall x<m,g(x)<g(m)$ 和 $\forall x>m,g(x)\le g(m)$,我们惊喜地发现 $m$ 是反素数,且大于 $m$ 的数都不是反素数,所以 $m$ 就是答案!接下来思考如何求解 $m$,先考虑质因数分解,$m=p_1^{c_1}p_2^{c_2}\cdots p_k^{c_k}$,根据 $m$ 是约数个数相同的数中最小的这一性质,感性理解就可以得到 $p_1\sim p_k$ 一定是前 $1\sim k$ 小的质数,且 $c_1\ge c_2\ge\cdots\ge c_k$,可以利用反证法证明之。显然需要预处理质数作为质因子,对于此题的数据范围,设 $p_i$ 为第 $i$ 个质数,发现 $\prod_{i=0}^{11}p_i>2\times 10^9$,因此只需要处理前 $11$ 个质数。接下来就是搜索,细节交由读者自行完成。
:::
## 最大公约数
#### 定义
若自然数 $d$ 同时是自然数 $a$ 和 $b$ 的约数,则称 $d$ 是 $a$ 和 $b$ 的公约数。在 $a$ 和 $b$ 的公约数中最大的一个,成为 $a$ 和 $b$ 的最大公约数,记为 $\gcd(a,b)$。
若自然数 $m$ 同时是自然数 $a$ 和 $b$ 的倍数,则称 $m$ 是 $a$ 和 $b$ 的公倍数。在 $a$ 和 $b$ 的公倍数中最小的一个,成为 $a$ 和 $b$ 的最小公倍数,记为 $\text{lcm}(a,b)$。
最大公约数、最小公倍数都可以根据定义扩展到三个及更多数上。
#### 定理
$$
\forall a,b\in\N,\ \gcd(a,b)\times\text{lcm}(a,b)=a\times b
$$
证明如下,设 $d=\gcd(a,b),a_0=\frac{a}{d},b_0=\frac{b}{d}$ 。根据最大公约数的定义,有 $\gcd(a_0,b_0)=1$ 。再根据最小公倍数的定义,有 $\text{lcm}(a_0,b_0)=a_0\times b_0$ 。于是 $\text{lcm}(a,b)=\text{lcm}(a_0\times d,b_0\times d)=\text{lcm}(a_0,b_0)\times d=a_0\times b_0\times d=\frac{a}{d}$ 。原式得证。
#### 九章算术·更相减损术
$$
\forall a,b\in\N,a\ge b,\ \gcd(a,b)=\gcd(b,a-b)=\gcd(a,a-b)\\
\forall a,b\in\N,\ \gcd(2a,2b)=2\gcd(a,b)
$$
证明如下,根据最大公约数的定义,后者显然成立,且将 2 替换为任意自然数也成立。主要证明前者,对于 $a,b$ 的任意公约数 $d$,因为 $d\mid a,d\mid b$,所以 $a$ 与 $b$ 的差是 $d$ 的倍数,即 $d\mid (a-b)$。因此 $d$ 也是 $b$,$a-b$ 的公约数。反之亦然成立。故 $a,b$ 的公约数集合与 $b,a-b$ 的公约数集合相同。于是它们的最大公约数也相等。对于 $a,a-b$ 同理。
#### 欧几里得算法
$$
\forall a,b\in\N,b\ne0,\ \gcd(a,b)=\gcd(b,a\bmod b)
$$
证明如下,进行分类讨论。
若 $a<b$,则 $\gcd(b,a\bmod b)=\gcd(b,a)=\gcd(a,b)$,显然成立。
若 $a\ge b$,则可以尝试运用更相减损术的结论证明,已知 $\forall a,b\in\N,a\ge b,\ \gcd(a,b)=\gcd(a,a-b)$,反复运用该结论,将 $a$ 减去 $b$,直至 $a<b$。此时得到的就是 $\gcd(a,b)=\gcd(b,a\bmod b)$。或设 $a=q\times b+r$,其中 $0\le r<b$。显然 $r=a\bmod b$。对于 $a,b$ 的任意公约数 $d$,因为 $d\mid a,d\mid q\times b$,故 $d\mid (a-q\times b)$,即 $d\mid r$,因此 $d$ 也是 $b,r$ 的公约数,反之亦然成立。故 $a,b$ 的公约数集合与 $b,a\bmod b$ 的公约数集合相同。于是它们的最大公约数自然也相等。
贴个代码:
~~~cpp
int gcd(int a,int b)
{
return b? gcd(b,a%b):a;
//注意此处的写法,gcd(a,0)=a
//部分编译器可以直接使用__gcd(a,b)求得
}
~~~
使用欧几里得算法求最大公约数的复杂度为 $\mathcal O(\log(a+b))$,底数为黄金分割比加 $1$,即$\frac{\sqrt 5+1}{2}$,证明比较复杂,在这里不给出。欧几里得算法是最常用的求最大公约数的算法。不过取模在高精度除法下不易实现,并且在大数据下取模的性能较差,在特定情况下可以使用更相减损术代替欧几里得算法。
如果要使用更相减损术的话,可以结合一个比较显然的结论降低时间复杂度,即假设 $a$ 为奇数,$b$ 为偶数,则 $\gcd(a,b)=\gcd(a,\frac{b}{2})$,可以使用算数右移计算 $\frac{b}{2}$。
## 扩展欧几里得算法
#### 裴蜀定理
对于任意整数 $a,b$,存在一对整数 $x,y$,满足 $ax+by=\gcd(a,b)$。其逆定理也成立,即对于 $a,b$ 的公因数 $d$,若存在一对整数 $x,y$,满足 $ax+by=d$,则 $d=\gcd(a,b)$。
证明如下,使用归纳法,将欧几里得算法的最后一步作为基础,即 $b=0$ 时,显然有一对整数 $x=1,y=0$,使得 $a\times 1+0\times 0=\gcd(a,0)$。若 $b>0$,则 $\gcd(a,b)=\gcd(b,a\bmod b)$。假设存在一对整数 $x,y$,满足 $b\times x+(a\bmod b)\times y=\gcd(b,a\bmod b)$,因为 $bx+(a\bmod b)y=bx+(a-b\lfloor \frac{a}{b}\rfloor)y=ay+b(x-\lfloor\frac{a}{b}\rfloor y)$,所以设 $x'=y,y'=x-\lfloor\frac{a}{b}\rfloor y$,就得到了 $ax'+by'=\gcd(a,b)$。最终可知裴蜀定理成立。
裴蜀定理是按照欧几里得算法的思路证明的,且上述证明同时给出了整数 $x$ 和整数 $y$ 的计算方法。这种计算方法被称为**扩展欧几里得算法**。
贴个代码:
~~~cpp
int exgcd(int a,int b,int &x,int &y)
{
if (b==0)
{
x=1;
y=0;
return a;
}
int d=exgcd(b,a%b,x,y);
int z=x;
x=y;
y=z-y*(a/b);
return d;
}
~~~
定义变量 $d,x_0,y_0$,调用 `d=exgcd(a,b,x0,y0)` 。注意在上述代码中,$x_0,y_0$ 是以引用的方式传递的。上述程序求出方程 $ax+by=\gcd(a,b)$ 的一组特解 $x_0,y_0$,并返回 $\gcd(x_0,y_0)$。
对于更一般的方程 $ax+by=c$,方程有解当且仅当 $d\mid c$。我们可以先求出 $ax+by=d$ 的一组特解 $x_0,y_0$,然后将 $x_0,y_0$ 同时乘上 $\frac{c}{d}$,就得到了 $ax+by=c$ 的一组特解 $\frac{c}{d}x_0,\frac{c}{d}y_0$。
事实上,方程 $ax+by=c$ 的通解可以表示为:
$$
x=\frac{c}{d}x_0+k\frac{b}{d},\ y=\frac{c}{d}y_0-k\frac{a}{d}\ (k\in\Z)
$$
其中 $d=\gcd(a,b)$,$x_0,y_0$ 是 $ax+by=\gcd(a,b)$ 的一组特解。
### 例题:[P1516 青蛙的约会](https://www.luogu.com.cn/problem/P1516)
>求关于 $k$ 的不定方程 $x+km-(y+kn)=tL,t\in\Z(1\le x\ne y\le 2\times10^9,1\le m,n\le 2\times10^9,1\le L\le2.1\times10^9)$ 的最小正整数解。
:::success[解法:]
题意转化的跨度比较大,读者可以先自行理解。将原式化为不定方程的一般形式,得到 $k(m-n)-tL=y-x$,设 $u=n-m,v=x-y$,则有 $uk+Lt=v$,若 $u<0$,则要将 $u,v$ 都取反。此时就可以运用扩展欧几里得算法求出一组特解 $k=k_0,t=t_0$,或在 $\gcd(t,k)\nmid v$ 的情况下报告无解。对于最小正整数解,有 $k=k_{\min}+\frac{L}{\gcd(u,L)}\times p,p\in\Z$,证明如下:设一般方程:$ax+by=c,ax_0+by_0=c$,则 $a(x-x_0)+b(y-y_0)=0$,两边同时除以 $\gcd(a,b)$,即 $\frac{a}{\gcd(a,b)}(x-x_0)=-\frac{b}{\gcd(a,b)}(y-y_0)$,注意到 $\gcd(\frac{a}{\gcd(a,b)},\frac{b}{\gcd(a,b)})=1$,所以 $\frac{b}{\gcd(a,b)}\mid(x-x_0)$,即对于任意 $x$ 有 $x=x_0+\frac{b}{\gcd(a,b)}\times k,k\in\Z$,原式得证,于是答案为 $k_{\min}=k_0\bmod\frac{L}{\gcd(u,L)}$。
:::
## 互质与欧拉函数
#### 定义
$\forall a,b\in\N$,若 $\gcd(a,b)=1$,则称 $a,b$ 互质。对于三个数或更多个数的情况,则 $\gcd(a,b,c)=1$ 的情况为 $a,b,c$ 互质, $\gcd(a,b)=\gcd(b,c)=\gcd(a,c)$ 为 $a,b,c$ 两两互质。后者显然是前者的充分不必要条件。
#### 欧拉函数
$1\sim N$ 中与 $N$ 互质的数的个数被称为欧拉函数,记为 $\varphi(N)$。
若在算数基本定理中,$N=p_1^{c_1}p_2^{c_2}\cdots p_m^{c_m}$,则:
$$
\varphi(N)=N\times\frac{p_1-1}{p_1}\times\frac{p_2-1}{p_2}\times\cdots\times\frac{p_m-1}{p_m}=N\times\prod_{\text{prime}|N}(1-\frac{1}{p})
$$
证明如下,设 $p$ 是 $N$ 的质因子, $1\sim N$ 中 $p$ 的倍数有 $p,2p,3p,\cdots,\frac{N}{p}\times p$,共 $\frac{N}{p}$ 个。同理,若 $q$ 也是 $N$ 的质因子,则 $1\sim N$ 中 $q$ 的倍数有 $\frac{N}{q}$ 个。如果去掉这 $\frac{N}{p}+\frac{N}{q}$ 个数,那么 $p\times q$ 的倍数被排除了两次,需要再加回来一次。这里使用了容斥原理。因此, $1\sim N$ 中不与 $N$ 含有共同质因子 $p$ 或 $q$ 的数的个数为:
$$
N-\frac{N}{p}-\frac{N}{q}+\frac{N}{pq}=N\times(1-\frac{1}{p}-\frac{1}{q}+\frac{1}{pq})=N(1-\frac{1}{p})(1-\frac{1}{q})
$$
类似地,我们可以在 $N$ 的全部质因子上使用容斥原理,即可得到 $1\sim N$ 中不与 $N$ 含有任何公共质因子的数的个数,也就是与 $N$ 互质的数的个数。该算法与莫比乌斯函数有关。
贴个代码:
~~~cpp
int phi(int n)
{
int ans=n;
for (int i=1;i*i<=n;i++)
{
if (n%i==0)
{
ans=ans/i*(i-1);
while (n%i==0)
n/=i;
}
}
if (n>1) ans=ans/n*(n-1);
return ans;
}
~~~
#### 积性函数
如果当 $a,b$ 互质时,有 $f(ab)=f(a)\times f(b)$,那么称数论函数 $f$ 为积性函数。
#### 一些性质
1. $\forall n>1$,$1\sim n$ 中与 $n$ 互质的数的和为 $n\times\frac{\varphi(n)}{2}$。
2. 若 $a,b$ 互质,则 $\varphi(ab)=\varphi(a)\times\varphi(b)$。
3. 若 $f$ 是积性函数,且在算数基本定理中 $n=\prod_{i=1}^{m}p_i^{c_i}$,则 $f(n)=\prod_{i=1}^{m}f(p_i^{c_i})$。
4. 设 $p$ 为质数,若 $p\mid n$ 且 $p^2\mid n$,则 $\varphi(n)=\varphi(\frac{n}{p})\times p$。
5. 设 $p$ 为质数,若 $p\mid n$ 但 $p^2\nmid n$,则 $\varphi(n)=\varphi(\frac{n}{p})\times(p-i)$。
6. $\sum_{d\mid n}\varphi(d)=n$。
证明如下:
1. 因为 $\gcd(n,x)=\gcd(n,n-x)$ 所以与 $n$ 不互质的数 $x,n-x$ 成对出现,平均值为 $\frac{n}{2}$。因此,与 $n$ 互质的数的数的平均值也是 $\frac{n}{2}$,进而得到性质 $1$ 。
2. 性质 $2$ 是显然的,将 $a,b$ 分解质因数即可得。
3. 性质 $3$ 也是显然的,根据积性函数的定义,将 $n$ 分解质因数即可得。
4. 根据性质 $4$ 的条件,可得 $n,\frac{n}{p}$ 包含相同的质因子,只是 $p$ 的质数不同。直接把 $\varphi(n)$ 与 $\varphi(\frac{n}{p})$ 按照欧拉函数的计算公式写出,二者相除,商为 $p$,得到性质 $4$。
5. 根据性质 $5$ 的条件,可得 $n,\frac{n}{p}$ 互质,由 $\varphi$ 是积性函数得 $\varphi(n)=\varphi(\frac{n}{p})\times\varphi(p)$,再由 $p$ 是质数得 $\varphi(n)=p-1$,性质 $5$ 成立。
6. 设 $f(n)=\sum_{d\mid n}\varphi(d)$。用乘法分配律展开,再利用 $\varphi$ 是积性函数,得到:若 $n,m$ 互质,则 $f(nm)=\sum_{d\mid nm}\varphi(d)=(\sum_{d\mid n}\varphi(d))\times(\sum_{d\mid m}\varphi(d))=f(n)\times f(m)$。即 $\sum_{d\mid n}\varphi(d)$ 是积性函数。对于单个质因子, $f(p^m)=\sum_{d\mid p^m}\varphi(d)=\varphi(1)+\varphi(p)+\varphi(p^2)+\cdots+\varphi(p^m)$ 是一个等比数列求和再加 $1$,结果为 $p^m$。所以 $f(n)=\prod_{i=1}^{m}f(p_i^{c_i})=\prod_{i=1}^{m}p_i^{c_i}=n$,所以性质 $6$ 成立。
### 例题:[P1891 疯狂 LCM](https://www.luogu.com.cn/problem/P1891)
>有 $T(T\le3\times10^5)$ 次询问,给定 $n(n\le10^6)$,求
>$$
>\sum^n_{i=1}\text{lcm}(i,n)
>$$
:::success[解法:]
题面非常直白,朴素算法也是显然的。但要想出正解,我们首先应该对原式进行转化,因为 $\text{lcm}$ 不易处理,尝试将其转化为 $\gcd$ 的形式:$n\sum^n_{i=1}\frac{i}{\gcd(i,n)}$,接下来需要用到一个处理和式经典的技巧,即再套上一个和式,得到:
$$
n\sum_{d\mid n}\sum^n_{i=1}\frac{i}{d}[d=\gcd(i,n)]
$$
似乎增加了求解的复杂度,其实不然,它为我们接下来应用欧拉函数埋下伏笔,我们将中括号中的等式两边同时除以 $d$,并且用 $i$ 代替 $\frac{i}{d}$,得到:
$$
n\sum_{d\mid n}\sum^{\frac{n}{d}}_{i=1}i[\gcd(i,\frac{n}{d})=1]
$$
设 $k=\frac{n}{d}$,由于当 $d\mid n$ 时,$k\mid n$,所以最后得到:
$$
n\sum_{k\mid n}\sum^{k}_{i=1}i[\gcd(i,k)=1]
$$
内层的和式要求我们求得 $1\sim k$ 中所有与 $k$ 互质的数之和,很可惜,仍然和欧拉函数不同。但是,根据前文的更相减损术,有 $\gcd(i,k)=\gcd(k-i,k)$,这说明这些与 $k$ 互质的数是对称的,每一对数的和为 $k$,所以就是:
$$
n\sum_{k\mid n}\frac{\varphi(k)}{2}k
$$
最后的解法就很简单了,$\mathcal O(n)$ 预处理 $\varphi$,$\mathcal O(n\log n)$ 预处理约数,$\mathcal O(1)$ 回答每次询问。
:::
# 同余
#### 定义
设给定整数 $a,b$,那么一定存在唯一的一对整数 $q,r$,满足 $a=qb+r,\ 0\le r<|a|$,称 $r$ 为 $a$ 除 $b$ 的**余数**。
若整数 $a$ 和整数 $b$ 除以整数 $m$ 的余数相等,则称 $a,b$ 模 $m$ **同余**,记为 $a\equiv b\pmod m$,等价于 $m\mid (a-b)$。关于同余一些性质,可以参考[这里](https://blog.csdn.net/weixin_43627118/article/details/103357784)。
#### 同余类与剩余系
对于 $\forall a\in[0,m-1]$,集合 $\{a+km\}(k\in\Z)$ 的所有数模 $m$ 同余,余数都是 $a$。该集合称为一个模 $m$ 的同余类,简记为 $\overline{a}$ 。
模 $m$ 的同余类一共有 $m$ 个,分别为 $\overline{0},\overline{1},\overline{2},\cdots,\overline{m-1}$。它们构成 $m$ 的**完全剩余系**。
$1\sim m$ 中与 $m$ 互质的数代表的同余类共有 $\varphi(m)$ 个,它们构成 $m$ 的**简化剩余系**。例如,模 $10$ 的简化剩余系为 $\{\overline{1},\overline{3},\overline{7},\overline{9}\}$。
简化剩余系关于模 $m$ 乘法封闭,这是因为若 $a,b(1\le a,b\le m$ 与 $m$ 互质,则 $a\times b$ 也不可能与 $m$ 有相同的质因子,用算数基本定理可以简单地证明,即 $a\times b$ 也与 $m$ 互质。再由余数的定义,即可得到 $a\times b \bmod m$ 也与 $m$ 互质,即 $a\times b\bmod m$ 也属于 $m$ 的简化剩余系,这一步也可以用算数基本定理得到。
#### 费马小定理
若 $p$ 是质数,则对于任意整数 $a$,有 $a^p\equiv a\pmod p$。
在证明欧拉定理的过程中可以证明费马小定理。
#### 欧拉定理
若正整数 $a,n$ 互质,则 $a^{\varphi(n)}\equiv 1 \pmod n$。
证明如下,设 $n$ 的简化剩余系为 $\{\overline{a_1},\overline{a_2},\cdots,\overline{a_{\varphi(n)}}\}$。对 $\forall a_i,a_j$,若 $a\times a_i\equiv a\times a_j\pmod n$,则 $a\times (a_i-a_j)\equiv 0$。因为 $a,n$ 互质,所以 $a_i-a_j\equiv 0$,即 $a_i\equiv a_j$。故当 $a_i \ne a_j$ 时,$aa_i,aa_j$ 也代表不同的同余类。又因为简化剩余系关于模 $m$ 乘法封闭,故 $\overline{aa_i}$ 也在简化剩余系集合中。因此,集合 $\{\overline{a_1},\overline{a_2},\cdots,\overline{a_{\varphi(n)}}\}$ 与集合 $\{\overline{aa_1},\overline{aa_2},\cdots,\overline{aa_{\varphi(n)}}\}$ 都能表示 $n$ 的简化剩余系。综上所述:
$$
a^{\varphi(n)}a_1a_2\cdots a_n\equiv (aa_1)(aa_2)\cdots(aa_{\varphi(n)})\equiv a_1a_2\cdots a_{\varphi(n)}\pmod n
$$
因此 $a^{\varphi(n)}\equiv 1\pmod n$。
当 $p$ 是质数时,$\varphi(n)=p-1$,并且只有 $p$ 的倍数与 $p$ 不互质。所以,只要 $a$ 不是 $p$ 的倍数,就有 $a^{p-1}\equiv 1\pmod p$,即 $a^p\equiv a$。另外,若 $a$ 是 $p$ 的倍数, $a^p\equiv a$ 显然成立,则费马小定理得证。
#### 欧拉定理的推论
若正整数 $a,n$ 互质,则对于任意正整数 $b$,有 $a^b\equiv a^{b\bmod \varphi(n)}\pmod n$。
证明如下,设 $b=q\times\varphi(n)+r$,其中 $0\le r<\varphi(n)$ ,即 $r=b\bmod\varphi(n)$。于是有 $a^b\equiv a^{q\times\varphi(n)+r}\equiv(a^{\varphi(n)})^q\times a^r\equiv 1^q\times a^r\equiv a^r\equiv a^{b\bmod\varphi(n)}\pmod n$。
#### 乘法逆元
若整数 $b,m$ 互质,并且 $b\mid a$,则存在一个数 $x$,使得 $a/b\equiv a\times x\pmod m$,称 $x$ 为 $b$ 的**模 $m$ 乘法逆元**,记为 $b^{-1}\pmod n$。
因为 $\frac{a}{b}\equiv a\times b^{-1}\equiv \frac{a}{b}\times b\times b^{-1}\pmod m$,所以 $b\times b^{-1}\equiv1\pmod m$。
如果模数是质数,则设 $p=m$,并且 $b<p$,根据费马小定理,$b^{p-1}\equiv 1\pmod p$,即 $b\times b^{p-2}\equiv 1\pmod p$。因此,当模数 $p$ 为质数时,$b^{p-2}$ 即为 $b$ 的乘法逆元,可以直接使用快速幂求解。
如果只是保证 $b,m$ 互质,那么乘法逆元可以通过求解同余方程 $b\times x\equiv 1\pmod m$ 得到。
## 线性同余方程
给定整数 $a,b,m$,求一个整数 $x$ 满足 $a\times x\equiv b\pmod m$,或者给出无解。因为未知数的指数为 $1$,所以称之为一次同余方程,也称为线性同余方程。
$a\times x\equiv b\pmod m$ 等价于 $a\times x-b$ 是 $m$ 的倍数,不妨设为 $-y$ 倍。于是,该方程可以改写为 $a\times x+m\times y=b$。
根据裴蜀定理及其证明,线性同余方程有解当且仅当 $\gcd(a,m)\mid b$。
在有解时,先使用扩展欧几里得算法求出一组整数 $x_0,y_0$ ,满足 $a\times x_0+m\times y_0=\gcd(a,m)$。然后 $x=x_0\times b/\gcd(a,m)$ 就是原线性同余方程组的一个解。方程的通解则是所有模 $\frac{m}{\gcd(a,m)}$ 与 $x$ 同余的整数。例如求最小非负整数解 $x_{\min}$,则 $x_{\min}=x_0\times \frac{b}{\gcd(a,m)}\bmod \frac{m}{\gcd(a,m)}$。
#### 中国剩余定理
设 $m_1,m_2,\cdots,m_n$ 是两两互质的整数,$m= \textstyle\prod_{m=1}^{n}m_i, M_i=\frac{m}{m_i}$,$t_i$ 是线性同余方程 $M_it_i\equiv 1\pmod m_i$ 的一个解。对于任意的 $n$ 个整数 $a_1,a_2\cdots,a_n$,方程组:
$$
\left\{\begin{matrix}
x\equiv a_1\pmod {m_1}\\
x\equiv a_2\pmod {m_2}\\
\vdots\\
x\equiv a_n\pmod {m_n}
\end{matrix}\right.
$$
有整数解,解为 $x=\textstyle\sum_{i=1}^na_iM_it_i$。
证明如下,因为 $M_i=\frac{m}{m_i}$,是除 $m_i$ 以外所有模数的倍数,所以 $\forall k\ne i,\ a_iM_it_i\equiv 0\pmod m_k$。又因为 $a_iM_it_i\equiv a_i\pmod m_i$,所以代入 $x=\textstyle\sum_{i=1}^na_iM_it_i$,原方程组成立。
中国剩余定理给出了模数两两互质的线性同余方程组的一个特解。方程组的通解可以表示为 $x+km(k\in\Z)$。例如求出最小非负整数解,只需把 $x$ 对 $m$ 取模即可。
贴个代码:
~~~cpp
int exgcd(int a,int b)
{
if (b==0)
{
x=1;
y=0;
return a;
}
int d=exgcd(b,a%b);
int tmp=x;
x=y;
y=tmp-y*(a/b);
return d;
}
int main()
{
for (int i=1;i<=n;i++)
{
//输入
mm*=m[i];
}
for (int i=1;i<=n;i++)
{
mi=mm/m[i];
exgcd(mi,m[i]);
ans=((ans+a[i]*mi*x)%mm+mm)%mm;
}
ans=(ans+mm)%mm;
return 0;
}
~~~
#### 扩展中国剩余定理
对于线性同余方程组中 $m_1,m_2,\cdots,m_n$ 两两不全互质的情况,中国剩余定理不再适用,原因在于只要任意两个模数不互质,就会导致 $M_i$ 与 $m_i$ 不互质的情况。在上文中,$t_i$ 是线性同余方程 $M_it_i\equiv 1\pmod {m_i}$ 的一个解,即 $M_i$ 在模 $m_i$ 意义下的逆元,如果 $M_i$ 与 $m_i$ 不互质,则无法求解逆元。
此时可以使用扩展中国剩余定理,算法思路基本上与中国剩余定理无关联,而是对方程进行合并。对于两个同余方程
$$
\left\{\begin{matrix}
x\equiv a_1\pmod {m_1}\\
x\equiv a_2\pmod {m_2}\\
\end{matrix}\right.
$$
有 $x\equiv tm_1+a_1\pmod {m_2}$,则 $tm_1+a_1\equiv a_2\pmod {m_2}$,即 $tm_1\equiv a_2-a_1\pmod {m_2}$,根据裴蜀定理,此时若 $\gcd(t,m_2)\nmid(a_2-a_1)$,则原方程组无解,反之则将方程两边同时除以 $m_1$,设 $d=\gcd(m_1,m_2)$,得 $t\equiv\frac{a_2-a_1}{m_1}\pmod{\frac{m_2
}{d}}$,使用扩展欧几里得求解得出 $t_0\equiv t\pmod {\frac{m_2}{d}}$,代回原式得 $x\equiv t_0m_1+a\pmod {\frac{m_1m_2}{d}}$,其中 $\frac{m_1m_2}{d}$ 即为 $\text{lcm}(m_1,m_2)$。
不断重复上述过程,最终可以将整个方程组和并为同一个方程,该方程解出来的 $x$ 即为原方程组的解。
### 例题:[P4777 【模板】扩展中国剩余定理(EXCRT)](https://www.luogu.com.cn/problem/P4777)
>模板,没有坑。
:::success[解法:]
按照上文思路即可。
:::
由于作者没有找到比较合适的例题,很多题目需要用 Lucas 定理或 BSGS 算法求解,或者是太裸的题,并且完成 exCRT 的模板已经具备一定难度了,因此选用模板作为例题。
本文只提供了一些基础且常用的基础数论知识,读者若想深入了解,可以去学习上文提到的莫比乌斯函数、[Lucas 定理](https://www.luogu.com.cn/problem/P3807)和 [BSGS 算法](https://www.luogu.com.cn/problem/P3846)。