专栏文章

简单数论

算法·理论参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mio77r3f
此快照首次捕获于
2025/12/02 14:29
3 个月前
此快照最后确认于
2025/12/02 14:29
3 个月前
查看原文

一.斐蜀定理

(1).内容:

a,bZa,b \in \mathbb{Z} 且不全为0,则x,yZ\forall x,y \in \mathbb{Z},满足gcd(a,b)ax+by\gcd(a,b) \mid ax+byx,yZ\exists x,y \in \mathbb{Z},使得ax+by=gcd(a,b)ax+by=\gcd(a,b)

(2).推广

1.逆定理

a,bZa,b \in \mathbb{Z} 且不全为0,若d>0d>0,且da,dbd \mid a,d \mid bx,yZ\exists x,y \in \mathbb{Z},使得ax+by=dax+by=d,则d=gcd(a,b)d=\gcd(a,b)

2.扩展

显然可以扩展到多个整数。

(3).进一步结论

对于a,bN,nZa,b \in \mathbb{N},n \in \mathbb{Z}aba \perp b,有以下几个结论:
  1. C=ababC=ab-a-b,显然有CC为奇数。
  2. 可得
{t=C,x,yN,ax+bytt>C,x,yN,ax+by=t \begin{cases} t=C,\forall x,y \in \mathbb{N}, ax+by \ne t\\ t>C,\exists x,y \in \mathbb{N}, ax+by = t \end{cases}
  1. 进而可得:对于方程 ax+by=cax+by=c,在 [0,C][0,C] 中,恰有 (a1)(b1)2\frac{(a-1)(b-1)}{2}cc 满足条件,即nN,n,Cn\forall n \in \mathbb{N},n,C-n 中有且只一个满足条件。

二.丢番图方程

(1).形态:a1x1b1+...+anxnbn=c,a1...n,b1...n,cZa_1x_1^{b_1}+...+a_nx_n^{b_n}=c,a_{1...n},b_{1...n},c \in \mathbb{Z}

(2).二元线性丢番图方程:ax+by=c,a,b,cZax+by=c,a,b,c \in \mathbb{Z}

1.定理:

对于a,b,cZ,x,yZ,使得ax+by=c    gcd(a,b)c对于a,b,c\in\mathbb{Z},\exists x,y \in \mathbb{Z},使得ax+by=c\iff\gcd(a,b)\mid c

2.求解:

a.求出一个解:扩展欧几里得

先求解ax+by=gcd(a,b)先求解ax+by=\gcd(a,b) 不妨假设a>b,gcd(a,b)=pa+qb不妨假设a>b,\gcd(a,b)=pa+qb 则有则有
ax+by=gcd(a,b)=gcd(b,amodb)=pb+q(amodb)=qa+(pqab)b\begin{aligned} ax+by &= \gcd(a,b)\\ &= \gcd(b,a \bmod b)\\ &= pb+q(a \bmod b)\\ &= qa+(p-q*\lfloor\frac{a}{b}\rfloor)b \end{aligned} CPP
int extended_gcd(int a,int b,int &x,int &y){
	if(!b){
		x=1,y=0;
		return a;
	}
	int ret,xx=x,yy=y;
	ret=extended_gcd(b,a%b,x,y);
	x=yy,y=xx-a/b*yy;
	return ret;
} 

b.所有解

x0,y0x_0,y_0 为原方程一组解,则有
{x=x0+bgcd(a,b)ty=y0agcd(a,b)t \begin{cases} x=x_0+\frac{b}{\gcd(a,b)}t\\ y=y_0-\frac{a}{\gcd(a,b)}t \end{cases}
为原方程一组解,其中t为任意整数为原方程一组解,其中t为任意整数
特殊地,我们有最大正整数解和最小正整数解的关系为:
{xmax=cyminbaymax=cxminab \begin{cases} x_{max}=\frac{c-y_{min}*b}{a}\\ y_{max}=\frac{c-x_{min}*a}{b} \end{cases}

三.线性同余方程

(1).形态:axc(modb)ax \equiv c \pmod b

(2).求解:

显然有axc(modb)    ax+by=c显然有 ax \equiv c \pmod b \iff ax+by=c
CPP
int extended_gcd(int a,int b,int &x,int &y){
	if(!b){
		x=1,y=0;
		return a;
	}
	int ret,tmp;
	ret=extended_gcd(b,a%b,x,y);
	tmp=x,x=y,y=tmp-a/b*y;
	return ret;
} 
bool linear_equation(int a,int b,int c,int &x,int &y){
	int d=extended_gcd(a,b,x,y);
	if(c%d) return 0;
	int k=c/d;
	x*=k,y*=k;
	return 1;
}

四.第一类指数同余方程

(1).形式:axb(modp)a^x\equiv b\pmod p

(2).求解

x=ktmx=kt-m,其中 t=pt=\lfloor\sqrt p\rfloor0mt0\le m\le t1kpt1\le k\le\lfloor\frac{p}{t}\rfloor
则有:aktmb(modp)a^{kt-m}\equiv b\pmod p
aktb1am(modp)a^{kt}b^{-1}\equiv a^m\pmod p
预处理出 a0modp,a1modp,,atmodpa^0\bmod p,a^1\bmod p,\dots,a^t\bmod p
枚举 kk,计算看有没有匹配上的数。
时间复杂度:O(p)O(\sqrt p)

五.第二类指数同余方程

(1).形式:xkb(modp)x^k\equiv b\pmod p

(2).求解:

aapp 的一个原根,先求出 bam(modp)b\equiv a^m\pmod p
假定 xayx\equiv a^y
akyam(modp)a^{ky}\equiv a^m\pmod p
akym1(modp)a^{ky-m}\equiv 1\pmod p
kym0(modp1)ky-m\equiv 0\pmod {p-1}

六.逆元

a×x1(modb)a \times x \equiv 1 \pmod b,则xxaamodb\bmod b意义下的倒数,记作a1a^{-1}
显然有 ab(modb)=a×b1(modb)\frac{a}{b} \pmod b=a\times b^{-1} \pmod b
  1. 扩展欧几里得: 前提:pp不一定是质数,aa为正整数,apa \perp p 同解线性同余方程
CPP
int extended_gcd(int a,int b,int &x,int &y){
	if(!b){
		x=1,y=0;
		return a;
	}
	int ret,xx=x,yy=y;
	ret=extended_gcd(b,a%b,x,y);
	x=yy,y=xx-a/b*yy;
	return ret;
} 
bool exgcd(int a,int b,int &x,int &y){
	int d=extended_gcd(a,b,x,y);
	if(1%d) return 0;
	int k=1/d;
	x*=k,y*=k;
	return 1;
}
  1. 快速幂:
    前提:pp为质数,aa为正整数,apa \perp p
根据费马小定理:若pp为质数,apa \perp p,则ap11(modp)a^{p-1} \equiv 1 \pmod p
则有
ax1(modp)axap1(modp)xap2(modp)\begin{aligned} ax &\equiv 1 \pmod p\\ ax &\equiv a^{p-1} \pmod p\\ x &\equiv a^{p-2} \pmod p \end{aligned}
  1. 线性算法: 前提:pp为质数,ii为正整数
显然有 11(modp)1^{-1} \pmod p
不妨设kkp/ip/i的商,r为p/ip/i的余数
ki+r=p\therefore k*i+r=p
ki+r0(modp)\therefore k*i+r \equiv 0 \pmod p
同乘i1r1i^{-1}r^{-1}可得:
ki1+i10(modp)\therefore k*i^{-1}+i^{-1}\equiv 0 \pmod p
i1kr1(modp)\therefore i^{-1} \equiv -k*r^{-1} \pmod p
i1pi(pmodi)1(modp)\therefore i^{-1} \equiv -\lfloor \frac{p}{i} \rfloor * (p \bmod i)^{-1} \pmod p
CPP
inv[1]=1;
for(int i=2;i<p;i++)
  inv[i]=(p-p/i)*inv[p%i]%p;

七.原根

modmod 的原根:gg 是原根当且仅当 g0,g1,,gp2g^0,g^1,\dots,g^{p-2}modmod 两两不同。
若模 modmod 意义下原根存在:
  • mod=1,2,4,pα,2pαmod=1,2,4,p^{\alpha},2p^{\alpha},其中 pp 是奇素数,αN+\alpha\in\mathbb{N}_+
  • 原根恰好有 φ(mod1)\varphi(mod-1)
  • 最小的原根一般不大,可以直接枚举
  • gg 是原根当且仅当 d(mod1),dmod1    gd1\forall d\mid(mod-1),d\ne mod-1\iff g^d\ne 1

八.二次剩余

勒让德符号:(ap)={0pa1x2a(modp)1otherwise\left(\dfrac{a}{p}\right)=\begin{cases}0&p\mid a\\1&\exists x^2\equiv a\pmod p\\-1&otherwise\end{cases}
欧拉准则:(ap)ap12(modp)\left(\dfrac{a}{p}\right)\equiv a^{\frac{p-1}{2}}\pmod p
二次互反律:对于奇素数 p,qp,q,有 (pq)(qp)=(1)(p1)(q1)4\left(\dfrac{p}{q}\right)\left(\dfrac{q}{p}\right)=(-1)^{\frac{(p-1)(q-1)}{4}}
求解 xx
前提:pp 为奇素数。
随机一个 aa,使得 a2na^2-n 为非二次剩余,令 w=a2nw=\sqrt{a^2-n}
x=(a+w)p+12x=(a+w)^{\frac{p+1}{2}}
CPP
LL w,n,p; 
struct num{
	LL x,y;
	num operator *(const num b){
		num tmp;
		tmp.x=((x*b.x%p+y*b.y%p*w%p)%p+p)%p;
		tmp.y=((x*b.y%p+y*b.x%p)%p+p)%p;
		return tmp;
	}
};
LL qpow(num x,LL y,LL Mod=mod) {
	if(y==0) return 1;
	num res=x; y--;
	for(;y;y>>=1,x=x*x)
		if(y&1) res=res*x;
	return res.x%Mod;
}
LL cipolla(LL n,LL p){
	n%=p;
	if(qpow(n,(p-1)/2,p)==p-1) return -1;
	LL a;
	while(1){
		a=(rnd_64()>>1ll)%p;
		w=(((a*a)%p-n)%p+p)%p;
		if(qpow(w,(p-1)/2,p)==p-1) break;
	}
	
	num x={a,1};
	return qpow(x,(p+1)/2,p);
}
void solve(){
	cin>>n>>p;
	if(!n){
		cout<<"0\n";
		return ;
	}
	LL ans1=cipolla(n,p),ans2=p-ans1;
	if(ans1==-1) cout<<"Hola!\n";
	else {
		if(ans1==ans2) cout<<ans1<<"\n";
		else cout<<min(ans1,ans2)<<" "<<max(ans1,ans2)<<"\n";
	}
	return ;
}

九.中国剩余定理

(1).内容:

若自然数 m1...rm_{1...r} 两两互质,记 M=m1m2...mrM=m_1m_2...m_r 则方程:
{xa1(modm1)xa2(modm2)...xar(modmr) \begin{cases} x \equiv a_1 \pmod {m_1}\\ x \equiv a_2 \pmod {m_2}\\ ...\\ x \equiv a_r \pmod {m_r} \end{cases}
modM意义下有唯一解在\bmod M意义下有唯一解

(2).过程:

  1. 计算 ni=Mmin_i=\frac{M}{m_i}
  2. 计算 nin_imodmi\bmod m_i 意义下的逆元 ni1{n_i}^{-1}
  3. 计算 ci=nini1c_i=n_i*{n_i}^{-1}(不对 mim_i 取模)
  4. 则方程在 modM\bmod M 意义下的唯一解为:x=i=1raici(modM)x=\sum_{i=1}^{r}a_ic_i \pmod M
CPP
int extended_gcd(__int128 a,__int128 b,__int128 &x,__int128 &y){
	if(!b){
		x=1,y=0;
		return a;
	}
	__int128 ret,tmp;
	ret=extended_gcd(b,a%b,x,y);
	tmp=x,x=y,y=tmp-a/b*y;
	return ret;
}
signed main(){
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	cin>>r;
	for1(i,1,r) cin>>m[i]>>a[i],M*=m[i];
	for1(i,1,r){
		n[i]=M/m[i];
		extended_gcd(n[i],m[i],x,y);
		c[i]=n[i]*x;
		madd(ans,a[i]*c[i],M);
	}
	cout<<ans;
    return 0;
}

(3).扩展中国剩余定理:

若模数不两两互质。
先考虑 xa1(modm1),xa2(modm2)x \equiv a_1 \pmod {m_1},x \equiv a_2 \pmod {m_2}
转化成不定方程 x=m1p+q1=m2q+a2x=m_1p+q_1=m_2q+a_2
m1pm2q=a2a1m_1p-m_2q=a_2-a_1
gcd(m1,m2)(a2a1)\gcd(m_1,m_2)\nmid(a_2-a_1) 则无解。
否则可以转化成 xm1p+a1(modlcm(m1,m2))x\equiv m_1p+a_1\pmod {lcm(m_1,m_2)}
CPP
__int128 extended_gcd(__int128 a,__int128 b,__int128 &x,__int128 &y){
	if(!b){
		x=1,y=0;
		return a;
	}
	__int128 ret,tmp;
	ret=extended_gcd(b,a%b,x,y);
	tmp=x,x=y,y=tmp-a/b*y;
	return ret;
}
bool linear_equation(__int128 a,__int128 b,__int128 c,__int128 &x,__int128 &y){
	__int128 d=extended_gcd(a,b,x,y);
	if(c%d) return 0;
	__int128 k=c/d;
	x*=k,y*=k;
	return 1;
}
void solve(){
	cin>>r;
	for1(i,1,r) {
		rin(m); rin(a);
		linear_equation(M,-m,a-A,p,q);
		A=M*p+A,M=lcm(M,m);
		madd(A,M,M);
	}
	rout(A);
	return ;
}

(4).大部翻倍法

CPP
void merge(LL &a1,LL &m1,LL a2,LL m2){
	if(m1<m2) swap(m1,m2),swap(a1,a2);
	while(a1%m2!=a2) a1+=m1;
	m1=lcm(m1,m2);
}
void solve(){
	cin>>n;
	v=0,d=1;
	for1(i,1,n){
		cin>>a>>m;
		a%=m;
		merge(v,d,a,m);
	}
	cout<<v<<"\n";
}

十.积性函数

(1).定义

积性函数:对于函数 f(x)f(x),若 a,bN+,gcd(a,b)=1,f(ab)=f(a)f(b)\forall a,b\in\mathbb{N}^+,\gcd(a,b)=1,f(ab)=f(a)f(b),则称 f(x)f(x) 为积性函数。
完全积性函数:对于函数 f(x)f(x),若 a,bN+,f(ab)=f(a)f(b)\forall a,b\in\mathbb{N}^+,f(ab)=f(a)f(b),则称 f(x)f(x) 为完全积性函数。
  • 常见的积性函数:φ,μ,σ,d\varphi,\mu,\sigma,d
  • 常见的完全积性函数:ε,I,id\varepsilon,I,id
其中:ε(n)=[n=1],I(n)=1,id(n)=n\varepsilon(n)=\left[n=1\right],I(n)=1,id(n)=n
积性函数的性质:
  • n=piαin=\prod p_i^{\alpha_i},那么 f(n)=f(piαi)f(n)=\prod f(p_i^{\alpha_i})
    • 于是可以用线性筛求出 g(n)=p1α1g(n)=p_1^{\alpha_1},然后 f(n)=f(g(n))f(ng(n))f(n)=f(g(n))f(\frac{n}{g(n)}),在 O(n)O(n) 时间内预处理积性函数的值。
  • f(n)f(n)g(n)g(n) 都是积性函数,那么 fgfgf/gf/g 都是积性函数。

(2).欧拉函数 φ\varphi

1.定义

n=i=1spikin=\prod_{i=1}^{s}{p_i}^{k_i},其中 pip_i 为质数,则 φ(n)=ni=1spi1pi\varphi(n)=n\prod_{i=1}^{s}\frac{p_i-1}{p_i},表示小于等于 nnnn 互质的数的个数$

2.性质:

  1. n为质数,φ(n)=n1若n为质数,\varphi(n)=n-1
  2. n为奇数,φ(n)=φ(2n)若n为奇数,\varphi(n)=\varphi(2n)
  3. ab,φ(ab)=φ(a)φ(b)若a \perp b,\varphi(ab)=\varphi(a)\varphi(b)
  4. n=dnφ(d)n=\sum_{d \mid n}\varphi(d)
  5. n=pk,p为质数,φ(n)=pkpk1若n=p^k,且p为质数,\varphi(n)=p^k-p^{k-1}

3.求法

a.单个:

CPP
int euler_phi(int n){
	int ans=n,sq=sqrt(n);
	for1(i,2,sq)
		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;
}

b.多个:

筛法:筛法:
p1n的最小质因子,n=np1,显然有φ(p1)=p11设p_1为n的最小质因子,n'=\frac{n}{p_1},显然有\varphi(p_1)=p_1-1
nmodp1=0,φ(n)=p1φ(n)若n'\bmod p_1=0,\varphi(n)=p_1*\varphi(n')
nmodp10,φ(n)=φ(p1)φ(n)若n'\bmod p_1\ne0,\varphi(n)=\varphi(p_1)*\varphi(n')
CPP
void euler_phi(int n){
	phi[1]=1;
	for1(i,2,n){
		if(!vis[i]) pri.p_b(i),phi[i]=i-1;
		for(int j: pri){
			if(i>n/j) break;
			vis[i*j]=1;
			if(i%j==0){
				phi[i*j]=phi[i]*j;
				break;
			}
			phi[i*j]=phi[i]*phi[j];
		}
	}
}

(3).莫比乌斯函数 μ\mu

1.定义

μ(n)={1n=10n的质因子最高次数>1(1)kn的质因子最高次数=1\mu(n)= \begin{cases} 1&n=1\\ 0&n的质因子最高次数>1\\ (-1)^k&n的质因子最高次数=1 \end{cases}
其中 kknn 的质因子个数。

2.性质

{1n=10n1\begin{cases} 1&n=1\\ 0&n\ne1 \end{cases}
dnμ(d)=ε(n),μ1=ε\sum\limits_{d\mid n}\mu(d)=\varepsilon(n),\mu\ast1=\varepsilon

3.求法

线性筛:
CPP
void get_mu(int n){
	mu[1]=1;
	for1(i,2,n){
		if(!vis[i]) pri.p_b(i),mu[i]=-1;
		for(int j: pri){
			if(i>n/j) break;
			vis[i*j]=1;
			if(i%j==0){
				mu[i*j]=0;
				break;
			}
			mu[i*j]=-mu[i];
		}
	}
}

(4).约数之和 σ\sigma 与 约数个数 dd

1.定义

n=p1α1×p2α2×pnαnn=p_1^{\alpha_1}\times p_2^{\alpha_2}\times\dots p_n^{\alpha_n}
则:
d(n)=(1+α1)×(1+α2)××(1+αn)d(n)=(1+\alpha_1)\times(1+\alpha_2)\times\dots\times(1+\alpha_n)
σ(n)=(1+p11+p12++p1α1)×(1+p21+p22++p2α1)××(1+pn1+pn2++pnα1)\sigma(n)=(1+p_1^1+p_1^2+\dots+p_1^{\alpha_1})\times(1+p_2^1+p_2^2+\dots+p_2^{\alpha_1})\times\dots\times(1+p_n^1+p_n^2+\dots+p_n^{\alpha_1}) =i=1n(j=0αipij)=\prod\limits_{i=1}^n(\sum_{j=0}^{\alpha_i}p_i^j) =i=1n1piαi+11pi=\prod\limits_{i=1}^n\frac{1-p_i^{\alpha_i+1}}{1-p_i}

2.求法

  1. 线性筛求 dd tit_i 表示 ii 的最小质因子的次数,即 min(α1,,αn)\min(\alpha_1,\dots,\alpha_n)
CPP
void make_d(){
    t[1]=d[1]=1;
    for1(i,2,n){
		if(!vis[i]) pri.p_b(i),t[i]=1,d[i]=2;
		for(int j: pri){
			if(i>n/j) break;
			vis[i*j]=1;
			if(i%j==0){
				t[i*j]=t[i]+1;
				d[i*j]=d[i]*(t[i*j]+1)/(t[i]+1);
				break;
			}
			t[i*j]=1;
			d[i*j]=d[i]*d[j];
		}
    }
}
  1. 线性筛求 σ\sigma ti=min(j=0α1p1j,,j=0αnpnj)t_i=\min(\sum_{j=0}^{\alpha_1}p_1^j,\dots,\sum_{j=0}^{\alpha_n}p_n^j)
CPP
void make_sgm(){
    sigma[1]=1;
    for1(i,2,n){
		if(!vis[i]) pri.p_b(i),t[i]=i+1,sigma[i]=i+1;
		for(int j: pri){
			if(i>n/j) break;
			vis[i*j]=1;
			if(i%j==0){
				t[i*j]=t[i]*j+1;
                sigma[i*j]=sigma[i]*t[i*j]/t[i];
				break;
			}
			t[i*j]=j+1;
			sigma[i*j]=sigma[i]*sigma[j];
		}
    }
}

十一.欧拉定理

(1).内容:

gcd(a,m)=1\gcd(a,m)=1,则 aφ(m)1(modm)a^{\varphi(m)} \equiv 1\pmod m

(2).扩展:

ab{abmodφ(m),gcd(a,m)=1ab,gcd(a,m)1,b<φ(m)a(bmodφ(m))+φ(m)gcd(a,m)1,bφ(m)(modm)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,m)\ne 1,b\ge\varphi(m) \end{cases} \pmod m

十二.威尔逊定理

对于素数 pp(p1)!1(modp)(p-1)!\equiv-1\pmod p

十三.数论分块

一般用来求形如 i=1nf(i)g(ni)\sum_{i=1}^nf(i)g(\lfloor\frac{n}{i}\rfloor)
若可以 O(1)O(1) 计算 f(r)f(l)f(r)-f(l) 时。
我们考虑将 ni\lfloor\frac{n}{i}\rfloor 相同的数放一起计算以使复杂度降至 O(n)O(\sqrt n)
CPP
LL H(LL n){
	LL ans=0;
	for(LL i=1,j;i<=n;i=j+1){
		j=n/(n/i);
		ans+=(j-i+1)*(n/i);
	}
	return ans;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...