数论,数学
gcd and lcm
Code
int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
int lcm(int a,int b){return a/gcd(a,b)*b;}
gcd的几条性质
证明:
\(\gcd(x^a-1,x^b-1)\)
\(=\gcd(x^b-1,x^a-x^b)\)
\(=\gcd(x^b-1,x^b(x^{a-b}-1))\)
\(=\gcd(x^b-1,x^{a-b}-1)\)
( \(fib[]\) 为广义斐波那契数列)
证明:
\(\gcd(fib[i+j],fib[j])\)
\(=\gcd(fib[j],fib[i+j]-fib[j])\)
\(=\gcd(fib[j],fib[i-1]*fib[j]+fib[i]*fib[j+1]-fib[j])\)
\(=\gcd(fib[j],fib[i]*fib[j+1])\)
\(=\gcd(fib[j],fib[i])\)
线性筛
int pr[maxn],tot;
bool check[maxn];
void init(int n){
check[1]=1;
for(int i=2;i<=n;i++){
if(!check[i]){
pr[++tot]=i;
}
for(int j=1;j<=tot&&i*pr[j]<=n;j++){
check[i*pr[j]]=1;
if(i%pr[j]==0)break;
}
}
}
理论上来讲 \(n\) 以内的质数个数大约在 \(n/\ln(n)\) 个左右
欧拉定理
设 \(S=\{x_1,x_2,...,x_{\varphi(n)}\}\) 为所有与 \(n\) 互质且 \(\le n\) 的数。
显然 \(x_i≡x_j(i≠j)(\% n)\) 不成立。
再设 \(T=\{a*x_1,a*x_2,...,a*x_{\varphi(n)}\}\)
\(\because \gcd(a,n)=1\)
\(\therefore a*x_i≡a*x_j(i≠j)(\% n)\) 不成立
\(\therefore S=T\)
\(\therefore \prod_{i=1}^{\varphi(n)}a*x_i≡\prod_{i=1}^{\varphi(n)}x_i(\% n)\)
\(\therefore a^{\varphi(n)}≡1(\% n)\)
扩展欧拉定理
费马小定理
\(a^{p-1}≡1(\% p)(p\text{ is prime})\)
Code
\(O(n)\) 求 \(1-n\) 的欧拉函数
void init(int n){
phi[1]=1;
for(int i=2;i<=n;i++){
if(!check[i]){
pr[++tot]=i;
phi[i]=i-1;
}
for(int j=1;j<=tot&&i*pr[j]<=n;j++){
check[i*pr[j]]=1;
if(i%pr[j]==0){
phi[i*pr[j]]=phi[i]*pr[j];
break;
}
else phi[i*pr[j]]=phi[i]*phi[pr[j]];
}
}
}
\(O(\sqrt{n})\) 求 \(n\) 的欧拉函数
int phi(int n){
int x=n,ret=n;
for(int i=2;i*i<=n&&x>1;i++){
if(x%i==0){
ret=ret/i*(i-1);
while(x%i==0)x/=i;
}
}
if(x>1)ret=ret/x*(x-1);
return ret;
}
逆元
逆元的引入
在做组合数取模的时候,常常要求\((a/b)\%p^{[1]}\),然而不同于加减乘,除法取模没有\((a/b)\%p=(a\%p/b\%p)\%p\)的性质。因此,我们引入乘法逆元的概念。
若\(a* b≡1(\%p)\),则设\(b=inv(a)\),称\(b\)是\(a\)的逆元,满足\((a*b)\%p=(a\%p*b\%p)\%p\)。这样,除法转换为乘法,就可以了。
所有的有理数都有一个与其对应的逆元。因此,对于两个整数\(A,B\),要计算\(\frac{A}{B}\)(实数除法)时,\(A\)不一定要被\(B\)整除。
对于两个取模过的数,逆元是怎么输出商的?它实际上是在对给定的取模过的数\(a,b\),找最小的两个\(A,B\),满足\(A=x* p+a,B=y* p+b,A\%B=0\),并返回\(A/B\)。
求逆元的几种常用方法
1. 扩展欧几里得
欧几里得定理
想必都知道$$gcd(a,b)=gcd(b,a%b)$$
解关于\(x,y\)的方程\(ax+by=gcd(a,b)\)
首先,我们先解出方程的一个特解,再通过特解推出其余的通解即可。
如何求特解
我们来看下面两个方程:
\(\because gcd(a,b)=gcd(b,a\%b),\)
\(\therefore ax_1+by_1=bx_2+(a\%b)y_2\)
\(\because a\%b=a-floor(a/b)* b^{[2]}\)
\(\therefore ax_1+by_1=ay_2+b(x_2-floor(a/b)* y_2)\)
由等式两边的系数关系得$$x_1=y_2$$$$y_1=x_2-floor(a/b)* y_2$$
于是形成了一种递归关系,可用递归解决。
递归终止状态
我们知道在计算最大公约数的过程中,\(b\)最终会等于\(0\),此时\(a=gcd(A,B)\),因此,这时方程化为\(a* x=gcd(A,B)\),解得\(x=1,y=0\)。
如何求通解
求得一组特解之后,我们发现,对于方程\(ax+by=gcd(a,b)\),当\(x\)增加\(b/gcd\),\(y\)减少\(a/gcd\)时,等式仍成立。
证明
\(ax\)项增加\(a* b/gcd\),\(by\)项减少\(a* b/gcd\)。
于是可求得所有通解。
如何求最小非负整数解
此处以\(x\)为例,\(y\)同理。我们让\(x\)一直减\(B/gcd\)直至求出最小解,即让\(x\%(B/gcd)\)即可。
解关于\(x,y\)的方程\(Ax+By=C\)
我们发现,当\(C\)不能整除\(gcd(A,B)\)时,方程就不能化为\(ax+by=gcd(a,b)\)的形式,因此就无解。否则有无数解,将方程两边同时除以\(\frac{C}{gcd(A,B)}\)求解即可。
Code
typedef long long D;
D egcd(D a,D b,D &x,D &y){
if(b==0){
x=1;
y=0;
return a;
}
D ans=egcd(b,a%b,x,y),tmp=x;
x=y;
y=tmp-a/b*y;
return ans;
}
D cal(D a,D b,D c){
D x,y,g=egcd(a,b,x,y);
if(c%g!=0)return -1;
b=abs(b/g);
x=(x*(c/g)%b+b)%b;
return x;
}
利用扩展欧几里得求乘法逆元
因为$$a* x≡1(%p)$$
所以$$a* x+b* y=1$$
此时,若\(1\%gcd(a,b)≠1\),即\(gcd(a,b)≠1\),则该方程无解。
否则,设特解为\(x_0\),最小非负整数解\(x=x_0\%m\)。当\(m<0\)时,由于计算机取模一个负数与数学上的意义不同,所以应把模数取绝对值。当\(x_0<0\)时,取模的结果是一个负数,所以把答案加上\(m\)即可。
复杂度为\(\log\)级。
Code
typedef long long D;
D egcd(D a,D b,D &x,D &y){
if(b==0){
x=1;
y=0;
return a;
}
D ans=egcd(b,a%b,x,y),tmp=x;
x=y;
y=tmp-a/b*y;
return ans;
}
D cal(D a,D m){
D x,y,g=egcd(a,m,x,y);
if(g!=1)return -1;
m=abs(m/g);
x=(x%m+m)%m;
return x;
}
2. 利用费马小定理
当\(p\)为质数时, \(a^{p-1}≡1(\%p)\) ,对\(a* x≡1(\%p)\)有\(x=a^{p-2}\%p\)。
复杂度为\(\log\)级。
Code
typedef long long D;
D qpow(D x,D y,D p){
D ans=1;
while(y){
if(y&1)ans=ans*x%p;
x=x*x%p;
y>>=1;
}
return ans;
}
D cal(D a,D p){
return qpow(a,p-2,p);
}
组合数取模(Lucas 定理)
由于题目中给的\(p\)一般都是质数,所以下面我们默认\(p\)为质数。
1. 错误方法
由上面的结论,我们得出$$C(n,m)=\frac{n!}{m!(n-m)!}=n!* inv(m!)* inv((n-m)!)$$
直接使用扩展欧几里得或费马小定理求逆元来实现除法取模。
此方法的错误之处在于,对\(a* x≡1(\%p),a\)有逆元的前提条件时\(a,p\)互质。当\(a,p\)不互质,即\(a\)是\(p\)的倍数时,不存在逆元,也就无法计算。
比如计算\(C(7,5)\%5\),正确答案应该是\(\frac{7* 6}{1* 2}\%5=21\%5=1\),但计算过程中出现了\(5\)的倍数,取模\(5\)之后就变为\(0\),因此最后答案输出了\(0\)。
2. Lucas定理
lucas定理可避免上述情况。
递归式:
设\(lucas(n,m,p)\)为\(C(n,m)\%p\) (\(p\)为质数),则
此处的\(C(n,m,p)\)可直接通过逆元计算。
复杂度为\(\log\)级。
证明
Code
typedef long long D;
D fac[100001];
void preparefac(D n,D p){
fac[0]=1;
for(D i=1;i<=n;i++){
fac[i]=i*fac[i-1]%p;
}
}
D qpow(D x,D y,D p){
D ans=1;
while(y>0){
if(y%2)ans=ans*x%p;
x=x*x%p;
y/=2;
}
return ans;
}
D cal(D x,D y){
return qpow(x,y-2,y);
}
D Div(D x,D y,D p){
return x*cal(y,p)%p;
}
D C_(D n,D m,D p){
if(m>n)return 0;
return Div(Div(fac[n],fac[m],p),fac[n-m],p);
}
D C(D n,D m,D p){
if(!m)return 1;
return C_(n%p,m%p,p)*C(n/p,m/p,p)%p;
}
线性递推求逆元
首先 \(1^{-1}≡1(\%p)\)
设 \(p=k* i+r\)
则 \(k* i+r≡0(\%p)\)
等式两边乘 \(i^{-1}* r^{-1}\)
得 \(k* r^{-1}+i^{-1}≡0(\%p)\)
\(\therefore i^{-1}≡-k* r^{-1}(\%p)\)
\(\therefore i^{-1}≡-floor(\frac{p}{i})* (p\%i)^{-1}(\%p)\)
Code
inv[1]=1;
inv[i]=(p-p/i)*inv[p%i]%p;
阶乘逆元
\(i\) 的阶乘逆元等于 \(i-1\) 的阶乘逆元乘以 \(i\) 的逆元。
Code
facinv[i]=facinv[i-1]*inv[i]%p;
CRT
用于求解一元线性同余方程组 \(x\equiv a_i\pmod{m_i}\)。
过程:
- \(b_i=\prod_{j\neq i}m_j\)
- \(c_i\equiv b_i^{-1}\pmod{m_i}\)
- \(ans=\sum_{i=1}^n a_ib_ic_i\pmod{\prod_i m_i}\)
证明
对于\(i\in[1,n]\),\(ans\equiv a_i+\sum_{j\neq i} a_jb_jc_j\pmod{m_i}\),由于\(m_i|b_j(j\neq i)\),\(\therefore ans\equiv a_i\pmod{m_i}\)
exCRT
对于多个方程的情况,考虑将方程两两合并。
对于两个方程的情况\(x\equiv a_1\pmod{m_1},x\equiv a_2\pmod{m_2}\)
转换:\(x=m_1s+a_1=m_2t+a_2 \Rightarrow m_1s-m_2t=a_2-a_1\),使用exgcd求解
当\(\gcd(m_1,m_2)\nmid a_2-a_1\)时无解
高端数论
积性函数
\(f(xy)=f(x)f(y)(x\perp y)\)
完全积性函数
\(f(xy)=f(x)f(y)\)
欧拉函数
定义
\(\varphi(n)=\sum_{i=1}^n [i\perp n]\)
性质
显然,除了它本身以外的数都和该质数互质。
与 \(p^k\) 不互质的数就是 \(p\) 的倍数,有 \(\frac{p^k}{p}=p^{k-1}\) 个。
设 \(S_x=\{\) 所有与 \(x\) 互质且 \(\le x\) 的数 \(\}\) 。显然 \(|S_x|=\varphi(x)\) 。
\(\because \gcd(a,b)=1,\)
\(\therefore S_{a*b}\) 与 \(S_a,S_b\) 一一对应。
\(\therefore |S_{a*b}|=|S_a|*|S_b|,\) 即 \(\varphi(a*b)=\varphi(a)*\varphi(b)\)
\(\varphi(2)=1\) ,易证。
\(\varphi(\frac{n}{p})=\frac{n}{p}*\prod (1-\frac{1}{p_i})\)
\(\varphi(n)=p*\frac{n}{p}*\prod (1-\frac{1}{p_i})=p*\varphi(\frac{n}{p})\)
\(\varphi(p)=p-1\) ,易证。
设 \(f(n)=\sum_{d|n}\varphi(d)\)
当 \(\gcd(x,y)=1\) 时, \(f(x)*f(y)=x\prod_{p_i是x的质因子}(1-\frac{1}{p_i})*y\prod_{p_i是y的质因子}(1-\frac{1}{p_i})=x*y\prod_{p_i是x*y的质因子}(1-\frac{1}{p_i})=f(x*y)\)
\(\therefore f(n)\) 是积性函数。
\(f(p^k)=\sum_{i=0}^k \varphi(p^i)=p^k\)
于是我们把 \(n\) 分解质因数:
\(n=\prod p_i^{k_i}\)
\(f(n)=\prod f(p_i^{k_i})=\prod p_i^{k_i}=n\)
公式
\(\varphi(x)=x\prod (1-\frac{1}{p_i})\)
\(p_i\) 为 \(x\) 的第 \(i\) 个质因子, \(x≥2\) 。 \(\varphi(1)=1\) 。
根据唯一分解定理, \(x=\prod p_i^{k_i}\) 。
\(\therefore \varphi(x)=\prod \varphi(p_i^{k_i})=\prod (p_i^{k_i}-p_i^{k_i-1})=x\prod (1-\frac{1}{p_i})\)
其他常用函数
\(\epsilon(n)=[n=1]\)
\(id(n)=n\)
\(1(n)=1\)
\(\sigma_k(n)=\sum_{d\mid n}d^k\)
其中\(\omega(n)\)表示\(n\)的本质不同质因子个数,是一个积性函数。
狄利克雷卷积
\((f*g)(n)=\sum_{d\mid n}f(d)g(\frac{n}{d})\)
例子
\(\varphi=\mu*id\)证明
\(\varphi*1=id \Rightarrow \varphi*1*\mu=id*\mu \Rightarrow \varphi*\epsilon=\mu*id\)
莫比乌斯反演
\(f(n)=\sum_{d\mid n}g(d)\Rightarrow g(n)=\sum_{d\mid n}\mu(d)f(\frac{n}{d})\)