$$ \newcommand{\seq}[2]{{#1}_{1},{#1}_{2},\cdots,{#1}_{#2}} \newcommand{\num}[1]{1,2,\cdots,#1} \newcommand{\stra}[2]{\begin{bmatrix}#1 \\ #2\end{bmatrix}} \newcommand{\strb}[2]{\begin{Bmatrix}#1 \\ #2\end{Bmatrix}} \newcommand{\dw}[1]{\underline{#1}} \newcommand{\up}[1]{\overline{#1}} $$

数论,数学

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)=x^{\gcd(a,b)}-1 \]

证明:
\(\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)\)

\[\gcd(fib[i],fib[j])=fib[\gcd(i,j)] \]

\(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)\) 个左右

欧拉定理

\[a^{\varphi(n)}≡1(\% n)(\gcd(a,n)=1) \]

\(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^b\equiv \begin{cases} a^{b\bmod\varphi(p)},\,&\gcd(a,\,p)=1\\ a^b,&\gcd(a,\,p)\ne1,\,b<\varphi(p)\\ a^{b\bmod\varphi(p)+\varphi(p)},&\gcd(a,\,p)\ne1,\,b\ge\varphi(p) \end{cases} \pmod p \]

费马小定理

\(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)\)

首先,我们先解出方程的一个特解,再通过特解推出其余的通解即可。

如何求特解

我们来看下面两个方程:

\[ax_1+by_1=gcd(a,b) \]

\[bx_2+(a\%b)y_2=gcd(b,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\)为质数),则

\[lucas(n,m,p)=C(n\%p,m\%p,p)* lucas(n/p,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}\)
过程:

  1. \(b_i=\prod_{j\neq i}m_j\)
  2. \(c_i\equiv b_i^{-1}\pmod{m_i}\)
  3. \(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]\)

性质

\[\varphi(p)=p-1(p\text{ is prime}) \]

显然,除了它本身以外的数都和该质数互质。

\[\varphi(p^k)=p^k-p^{k-1}(p\text{ is prime}) \]

\(p^k\) 不互质的数就是 \(p\) 的倍数,有 \(\frac{p^k}{p}=p^{k-1}\) 个。

\[\varphi(a*b)=\varphi(a)*\varphi(b)(\gcd(a,b)=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*n)=\varphi(n)(n\% 2=1) \]

\(\varphi(2)=1\) ,易证。

\[\varphi(n)=\varphi(\frac{n}{p})*p(p|\frac{n}{p}) \]

\(\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(n)=\varphi(\frac{n}{p})*(p-1)(p\text{ is prime},p|n,\gcd(p,\frac{n}{p})=1) \]

\(\varphi(p)=p-1\) ,易证。

\[\sum_{d|n}\varphi(d)=n \]

\(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})\)

例子

\[\epsilon=\mu*1 \]

\[\sigma_0=1*1 \]

\[\sigma=id*1 \]

\[\varphi=\mu*id \]

\(\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})\)


注:
[1] 在本文中,\(\%\)表示取模运算,等价于\(\text{mod}\)
[2] \(floor(x)\)表示\(\lfloor x \rfloor\)
posted @ 2018-10-27 20:22  chc_1234567890  阅读(470)  评论(0编辑  收藏  举报