数论

拓展欧几里得(exgcd)

P1082 [NOIP 2012 提高组] 同余方程

P5656 【模板】二元一次不定方程 (exgcd)

扩展欧几里得算法是在普通欧几里得算法(求最大公约数)的基础上,通过回溯过程记录系数,最终得到满足 \(ax + by = gcd(a, b)\) 的一组解 \((x,y)\)。核心逻辑是利用递归的思想,将大问题分解为小问题,直到递归边界 \((b=0)\),再反向推导系数。

int exgcd(int a,int b,int &x,int &y){
  if(!b){
    x=1,y=0;
    return a;
  }
  int d=exgcd(b,a%b,y,x);
  //d=exgcd(b,a%b,y,x)=b*y+(a-(a/b)*b)*x=a*x+b*(y-(a/b)*x)
  y-=a/b*x;
  return d;
}

欧拉函数

P2158 [SDOI2008] 仪仗队

P4139 上帝与集合的正确用法

欧拉函数(Euler's totient function),即 \(\varphi(n)\),表示的是小于等于 \(n\)\(n\) 互质的数的个数.当 \(n\) 是质数的时候,显然有 \(\varphi(n) = n - 1\)

性质:欧拉函数是积性函数,即对任意满足 \(\gcd(a, b) = 1\) 的整数 \(a,b\),有 \(\varphi(ab) = \varphi(a)\varphi(b)\).特别地,当 \(n\) 是奇数时 \(\varphi(2n) = \varphi(n)\)

普通求 \(phi\),时间复杂度 \(O(n\log n)\):

void Phi(int n){
	for(int i=1;i<=n;i++) phi[i]=i;
	for(int i=2;i<=n;i++){
		if(phi[i]==i){
			for(int j=i;j<=n;j+=i) phi[j]=phi[j]/i*(i-1);
		}
	}
}

线性筛求 \(phi\),时间复杂度 \(O(n)\):

void init(int n){
	phi[1]=1;
	for(int i=2;i<=n;i++){
		if(!isprime[i]) primes[++cnt]=i,phi[i]=i-1;
		for(int j=1;i*primes[j]<=n;j++){
			isprime[i*primes[j]]=1;
			if(i%primes[j]==0){
				phi[i*primes[j]]=phi[i]*primes[j];
				break;	
			}
			phi[i*primes[j]]=phi[i]*phi[primes[j]];
		}
	}
}

扩展欧拉定理

P5091 【模板】扩展欧拉定理

费马小定理:设 \(p\) 是素数.对于任意整数 \(a\)\(p\nmid a\),都成立 \(a^{p-1}\equiv 1\pmod p\).

欧拉定理:对于整数 \(m>0\) 和整数 \(a\),且 \(\gcd(a,m)=1\),有 \(a^{\varphi(m)}\equiv 1\pmod{m}\).

扩展欧拉定理

把欧拉定理推广到了底数与指数不互素的情形.

\[a^k \equiv \begin{cases} a^{k \bmod \varphi(m)} & \gcd(a,m)=1, \\ a^{k \bmod \varphi(m) + \varphi(m)} & \gcd(a,m) \neq 1,\ k < \varphi(m), \\ a^{(k \bmod \varphi(m)) + \varphi(m)} & \gcd(a,m) \neq 1,\ k \geq \varphi(m) \end{cases} \pmod{m}\]

拓展中国剩余定理

中国剩余定理

P1495 【模板】中国剩余定理(CRT)/ 曹冲养猪

中国剩余定理(Chinese Remainder Theorem, CRT) 可求解如下形式的一元线性同余方程组(其中 \(n_1, n_2, \cdots, n_k\) 两两互质):

\[\begin{cases} x \equiv a_1 \pmod{n_1} \\ x \equiv a_2 \pmod{n_2} \\ \vdots \\ x \equiv a_k \pmod{n_k} \end{cases}\]

过程

  • 计算所有模数的积 \(n\)

  • 对于第 \(i\) 个方程:

1.计算 \(m_i=\frac{n}{n_i}\)
2.计算 \(m_i\) 在模 \(n_i\) 意义下的 逆元 \(m_i^{-1}\)
3.计算 \(c_i=m_im_i^{-1}\)不要对 \(n_i\) 取模).

  • 方程组在模 \(n\) 意义下的唯一解为:\(x=\sum_{i=1}^k a_i\times c_i \pmod n\)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=20;
ll a[N],b[N],x,y,ans;
ll ksm(ll a,ll b,ll p){
	ll ans=0;
	while(b){
		if(b&1) ans=(ans+a)%p;
		a=(a+a)%p;
		b>>=1;
	}
	return ans;
}
ll exgcd(ll a,ll b){
	if(!b){
		x=1,y=0;
		return a;
	}
	ll d=exgcd(b,a%b);
	ll t=x;
	x=y,y=t-a/b*y;
	return d;
}
ll lcm(ll a,ll b){
	return a*b/exgcd(a,b);
}
int main(){
	int n;
	ll M=1,m;
	cin>>n;
	for(int i=1;i<=n;i++){//x ≡ a[i] (mod b[i])
		cin>>b[i]>>a[i];
		M*=b[i];
	}
	for(int i=1;i<=n;i++){
		m=M/b[i];
		exgcd(m,b[i]);//计算 m 的逆元 (m*x+b[i]*y)%b[i]=1
		for(int j=1;j<=a[i];j++) ans=((ans+m*x)%M+M)%M;
	}
	cout<<ans;
	return 0;
}

扩展中国剩余定理

P4777 【模板】扩展中国剩余定理(EXCRT)

P4774 [NOI2018] 屠龙勇士

解决 \(n_1, n_2, \cdots, n_k\) 不满足两两互质时的同余方程组 .

1.考虑两个方程

\[\begin{cases} x \equiv a_1 \ (\bmod\ m_1) \\ x \equiv a_2 \ (\bmod\ m_2) \end{cases} \]

这等价于:

\[x = a_1 + m_1 t_1 = a_2 + m_2 t_2 \]

其中 \((t_1, t_2)\) 是整数。

整理得:

\[\begin{align*} &m_1 t_1 - m_2 t_2 = a_2 - a_1 \\ \Rightarrow &m_1 t_1 + m_2 (-t_2) = a_2 - a_1 \\ \Rightarrow &m_1 t_1 \equiv a_2 - a_1 \ (\bmod\ m_2) \end{align*} \]

2.解的存在条件

\(d=\gcd(m_1,m_2)\).

方程 \(m_1 t_1 \equiv a_2 - a_1 \ (\bmod\ m_2)\) 有解当且仅当 \(d \mid (a_2 - a_1)\)

3. 合并为一个新方程

如果 \(d\mid(a_2-a_1)\),我们可以解这个同余方程:
两边除以 \(d\)

\[\frac{m_1}{d} t_1 \equiv \frac{a_2 - a_1}{d} \ \left(\bmod\ \frac{m_2}{d}\right) \]

\(m_1' = \frac{m_1}{d},\ m_2' = \frac{m_2}{d}\),则 \(\gcd(m_1',m_2')=1\)

解出

\[t_1 \equiv k \ \left(\bmod\ m_2'\right) \]

其中 \(k\) 是某个特解(用扩展欧几里得算法求得),\(t_1 = k + m_2' \cdot T\)\(T\) 是任意整数。

代回 \(x = a_1 + m_1 t_1\),于是:

\[x = a_1 + m_1 (k + m_2' T) = a_1 + m_1 k + \frac{m_1 m_2}{d} T \]

4. 合并结果

令:

\[x_0 = a_1 + m_1 k \]

\[M = \mathrm{lcm}(m_1, m_2) = \frac{m_1 m_2}{d} \]

则解为:

\[x \equiv x_0 \ (\bmod\ M) \]

这样我们把两个方程合并成了一个同余方程:

\[x \equiv x_0 \ (\bmod\ M) \]

5. 算法步骤(n 个方程)

  1. 初始化:$ x = a_1,m = m_1$,即当前解为 \(x\equiv a_1 \ (\bmod\ m_1)\)

  2. 对于 $ i = 2 $ ~ $n $:

  • 当前已知解为 $ x \equiv a \ (\bmod\ m) $,下一个方程 $ x \equiv a_i \ (\bmod\ m_i) $
  • 即 $ x = a + m t $,代入第 \(i\) 个方程:

    \[a + m t \equiv a_i \ (\bmod\ m_i) \]

    \[m t \equiv a_i - a \ (\bmod\ m_i) \]

  • 令 $ d = \gcd(m, m_i) $
  • 如果 $ d \nmid (a_i - a) $,无解,结束
  • 否则,解:

    \[\frac{m}{d} t \equiv \frac{a_i - a}{d} \ \left(\bmod\ \frac{m_i}{d}\right) \]

  • 用扩展欧几里得求 $t \equiv k \ (\bmod \frac{m_i}{d}) $
  • 更新:

    \[x \leftarrow a + m \cdot k \]

    \[m \leftarrow \mathrm{lcm}(m, m_i) = m \cdot (m_i / d) \]

    (注意取模,让 $ x $ 保持在 $ [0, m) $ 内)
  1. 最终解为 $ x \ \bmod\ m $,最小非负解是 $ (x+m) \bmod m $。
posted @ 2026-02-03 18:53  筝小鱼  阅读(0)  评论(0)    收藏  举报