信息学竞赛中可能用到的初等数论

竞赛中会用到的初等数论

0. 线性筛

[ 1 , n ] [1,n] [1,n]的范围内找质数,复杂度线性 O ( n ) O(n) O(n)

基于一个简单的想法:每个合数只在他的最小质因数删去。

我们要删去的数 x x x,
x = p 0 × f n t l x=p_{0}\times f_{ntl} x=p0×fntl
其中 p 0 p_{0} p0 x x x的最小质因数, f n t l f_{ntl} fntl x x x的次大因数。

void GetPrime(int n)
{
	memset(isPrime, 1, sizeof(isPrime));
	isPrime[1] = 0;
	
	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; //当i里有Prime[j]这个因子的时候,Prime[j+1]一定不是i*Prime[j+1]的最小质因数,所以终止,下个不用做了,因为不满足最初的"简单的想法"
		}
	}
}

后话:如果把 i s P r i m e [ i ] isPrime[i] isPrime[i]看成一个函数的话,表示i是不是一个质数,那么这里其实是在用递推求值。边界条件其实是 i i i为质数的时候,函数的值为1。当然这个函数不满足积性(下一节会讲到)。

1. 欧拉函数

欧拉函数 ϕ ( x ) \phi(x) ϕ(x),表示的是范围 [ 1 , x ] [1,x] [1,x]中与x互质的整数的个数。举几个例子, ϕ ( 1 ) = 0 ,   ϕ ( 2 ) = 1 ,   ϕ ( 3 ) = 2 ,   ⋯ \phi(1)=0,\ \phi(2)=1,\ \phi(3)=2,\ \cdots ϕ(1)=0, ϕ(2)=1, ϕ(3)=2, 

容易观察到,对于任意一个质数 p p p, ϕ ( p ) = p − 1 \phi(p)=p-1 ϕ(p)=p1

接下来考虑 ϕ ( p k ) \phi(p^k) ϕ(pk),由于 p k p^k pk只有唯一的质因数p,所以一个与其不互质的数一定包含因子p。所以 [ 1 , p k ] [1,p^k] [1,pk]中的p的倍数都与 p k p^k pk不互质,其他都与其互质。这个范围内p的倍数总共有 p k − 1 p^{k-1} pk1个。因此,
ϕ ( p k ) = p k − p k − 1 = ( p − 1 ) p k − 1 \phi(p^k)=p^k-p^{k-1}=(p-1)p^{k-1} ϕ(pk)=pkpk1=(p1)pk1

下面证明一下 ϕ ( x ) \phi(x) ϕ(x)具有一下性质,
对于 ( x , y ) = 1 (x,y)=1 (x,y)=1,有 ϕ ( x ⋅ y ) = ϕ ( x ) ⋅ ϕ ( y ) \phi(x\cdot y)=\phi(x)\cdot \phi(y) ϕ(xy)=ϕ(x)ϕ(y)

这里用Dirichlet卷积,对交换代数有兴趣的话,同样也可以验证环同态,这个放在Appendix里。

考虑集合 A d = { i ∣ ( x , i ) = d } ,   d ∣ x   即 d 为 x 的 一 个 因 数 。 A_d=\{i|(x,i)=d\},\ d|x\ 即d为x的一个因数。 Ad={i(x,i)=d}, dx dx
∣ A d ∣ = ϕ ( x / d ) |A_d|=\phi(x/d) Ad=ϕ(x/d)
显然有上式(觉得不显然的可以考虑 i = k ⋅ d i=k\cdot d i=kd的系数k,满足条件时,有几种取值),

x = ∑ d ∣ x ϕ ( x / d ) x=\sum_{d|x}\phi(x/d) x=dxϕ(x/d)

写成Dirichlet卷积形式

1 ∗ ϕ ( x ) = ∑ d ∣ x ϕ ( x / d ) = x 1*\phi(x)=\sum_{d|x}\phi(x/d)=x 1ϕ(x)=dxϕ(x/d)=x

1的卷积逆是Mobius的 μ \mu μ, 所以 ϕ ( x ) = μ ∗ x \phi(x)=\mu*x ϕ(x)=μx,两个积性函数的卷积还是积性函数,所以欧拉函数也是积性函数。

有了积性和唯一分解定理可以写出欧拉函数的通项

x的唯一质因数分解:
x = p 1 k 1 p 2 k 2 ⋯ p n k n x=p_1^{k_1} p_2^{k_2}\cdots p_n^{k_n} x=p1k1p2k2pnkn
t h e n   ϕ ( x ) = ( p 1 − 1 ) k 1 − 1 ( p 2 − 1 ) k 2 − 1 ⋯ ( p n − 1 ) k n − 1 then\ \phi(x)=(p_1-1)^{k_1-1}(p_2-1)^{k_2-1}\cdots (p_n-1)^{k_n-1} then ϕ(x)=(p11)k11(p21)k21(pn1)kn1

然后可以愉快的用这三个式子来做递推

ϕ ( x ) = x − 1 x 为 质 数 ϕ ( i × p r i m e ( j ) ) = ϕ ( i ) × ϕ ( p r i m e [ j ] ) ( i , p r i m e [ j ] ) = 1 ϕ ( i × p r i m e ( j ) ) = ϕ ( i ) × p r i m e [ j ] ( i , p r i m e [ j ] ) = p r i m e [ j ] \begin{aligned} \phi(x) &= x-1 & x为质数 \\ \phi(i\times prime(j))=&\phi(i)\times \phi(prime[j]) &(i,prime[j])=1\\ \phi(i\times prime(j))=&\phi(i)\times prime[j] &(i,prime[j])=prime[j]\\ \end{aligned} ϕ(x)ϕ(i×prime(j))=ϕ(i×prime(j))==x1ϕ(i)×ϕ(prime[j])ϕ(i)×prime[j]x(i,prime[j])=1(i,prime[j])=prime[j]

void GetPrime(int n)
{
	memset(isPrime, 1, sizeof(isPrime));
	isPrime[1] = 0;
	
	for(int i = 2; i <= n; i++) //穷举次大因数
	{
		if(isPrime[i]){
			Prime[++cnt] = i; 
			phi[i]=i-1;//i为质数
        }	
		for(int j = 1; j <= cnt && i*Prime[j] <= n; j++) //穷举最小质因数
		{
			isPrime[i*Prime[j]] = 0;
            phi[i*Prime[j]]=phi[i]*phi[Prime[j]];//i Prime[j]互质
			if(i % Prime[j] == 0) {
				phi[i*Prime[j]]=phi[i]*Prime[j];//i Prime[j]不互质
				break; 
			}
		}
	}
}

求单个数的欧拉函数可以用通项和因式分解求。
同样利用 ∣ A d ∣ = ϕ ( x / d ) |A_d|=\phi(x/d) Ad=ϕ(x/d)
可以使用分块法解决一些求和问题,比如求 ∑ i = 1 n ( i , n ) = ∑ d ∣ n d × ϕ ( n / d ) \sum_{i=1}^n (i,n)=\sum_{d|n} d\times \phi(n/d) i=1n(i,n)=dnd×ϕ(n/d)
习题:P2158

2. 费马小定理和欧拉定理

i.欧拉定理

对于任意正整数a和x, a ϕ ( x ) ≡ 1 m o d    x a^{\phi(x)}\equiv 1 \mod x aϕ(x)1modx

ii.费马小定理

对于任意正整数a和质数p, a p − 1 ≡ 1 m o d    p a^{{p-1}}\equiv 1 \mod p ap11modp
证明放在附录里,用的是群论的Lagrange Theorem
费马小定理可以用来判断一个数质数,用快速幂可以达到 O ( lg ⁡ n ) O(\lg n) O(lgn)的复杂度,也可以用来求一个数关于p的数论倒数
a ( p − 2 ) a ≡ 1 m o d    p a^{(p-2)} a \equiv 1\mod p a(p2)a1modp
a ( p − 2 ) ≡ a − 1 m o d    p a^{(p-2)} \equiv a^{-1} \mod p a(p2)a1modp

3. 裴蜀定理

两个整数 a , b a , b a,b, 最大公约数为 ( a , b ) = d (a,b)=d (a,b)=d ∃ \exist 整数 x ,   y x,\ y x, y, 满足 a x + b y = d ; ax+by=d; ax+by=d;
∀ \forall 整数 x ,   y x,\ y x, y,
a x + b y ≡ 0 m o d    d ax+by\equiv 0 \mod d ax+by0modd
证明很简单,这里就不展开讲了 有兴趣的同学自己去证明一下。
下面一节会去解决这个求这个a, b的问题。

4. 辗转相除和扩展欧几里得以及求逆元

辗转相除法可以看成一个递归, 递归式是 ( a , b ) = ( b , a % b ) (a,b)=(b,a\%b) (a,b)=(b,a%b),边界条件为 ( a , 0 ) = a (a,0)=a (a,0)=a.
正确性很容易证明,复杂度在1844年被一个法国人计算出来,结果是不会大于 5 lg ⁡ m i n ( a , b ) 5\lg min(a,b) 5lgmin(a,b),标志着算法复杂度理论的开端。

这里提供一种构造Fibonacci的夹逼证明,
Proof
Statement 1: 如果一组a, b在n步辗转相除计算出结果,那么有 a > = f n + 2 b > = f n + 1 a>=f_{n+2}\\b>=f_{n+1} a>=fn+2b>=fn+1
f n f_n fn为Fibonacci数列的第n项。
这里可以用数学归纳法证明:
当第n步满足考虑(n+1)时,
a n + 1 = ⌊ a n + 1 b n + 1 ⌋ a n + b n > = ⌊ a n + 1 b n + 1 ⌋ f n + 2 + f n + 1 > = f n + 2 + f n + 1 = f n + 3 a_{n+1}=\lfloor \frac{a_{n+1}}{b_{n+1}} \rfloor a_n+b_n>=\lfloor \frac{a_{n+1}}{b_{n+1}} \rfloor f_{n+2}+f_{n+1}>=f_{n+2}+f_{n+1}=f_{n+3} an+1=bn+1an+1an+bn>=bn+1an+1fn+2+fn+1>=fn+2+fn+1=fn+3
下面只需要考虑Fibonacci的第n项是多少就可以了,如果学过矩阵乘法或者求矩阵特征向量特征根的话那就很容易了,如果没有的话可以去学一学,这里直接给出通项。
f n = ( 1 + 5 2 ) n − ( 1 − 5 2 ) n 5 f_n=\frac{(\frac{1+\sqrt{5}}{2})^n-(\frac{1-\sqrt{5}}{2})^n}{\sqrt{5}} fn=5 (21+5 )n(215 )n
显然 f n f_n fn n n n是指数关系,即 f n = a n ,   a > 1 f_n=a^n,\ a>1 fn=an, a>1
所以由 b n ≈ f n + 1 b_n\approx f_{n+1} bnfn+1可以得到, n ≈ log ⁡ a b n \approx \log_a{b} nlogab

以上为辗转相除的复习

下面考虑这样一个问题,即解决裴蜀定理,已知a,b
a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)
求一组整数解x, y。

考虑辗转相除法:
边界条件: a x ( n ) + 0 ⋅ y ( n ) = g c d ( a , 0 ) = a ax^{(n)}+0\cdot y^{(n)}=gcd(a,0)=a ax(n)+0y(n)=gcd(a,0)=a
显然有一组解: x ( n ) = 1 ,   y ( n ) = 0 x^{(n)}=1,\ y^{(n)}=0 x(n)=1, y(n)=0

第一层: a x ( k ) + b y ( k ) = g c d ( a , b ) ax^{(k)}+by^{(k)}=gcd(a,b) ax(k)+by(k)=gcd(a,b)
第二层: b x ( k + 1 ) + r y ( k + 1 ) = g c d ( b , r ) ,   a ≡ r m o d    b bx^{(k+1)}+ry^{(k+1)}=gcd(b,r),\ a \equiv r \mod b bx(k+1)+ry(k+1)=gcd(b,r), armodb
g c d ( a , b ) = g c d ( b , r ) gcd(a,b)=gcd(b,r) gcd(a,b)=gcd(b,r), 和上面两式结合有: a x ( k ) + b y ( k ) = b x ( k + 1 ) + r y ( k + 1 ) ax^{(k)}+by^{(k)}=bx^{(k+1)}+ry^{(k+1)} ax(k)+by(k)=bx(k+1)+ry(k+1)
r = a − ⌊ a b ⌋ b r=a-\lfloor \frac{a}{b}\rfloor b r=abab
a x ( k ) + b y ( k ) = b x ( k + 1 ) + ( a − ⌊ a b ⌋ b ) ⋅ y ( k + 1 ) ax^{(k)}+by^{(k)}=bx^{(k+1)}+(a-\lfloor \frac{a}{b}\rfloor b)\cdot y^{(k+1)} ax(k)+by(k)=bx(k+1)+(abab)y(k+1)
上式左右两边相等可以得到:
x ( k ) = y ( k + 1 ) y ( k ) = x ( k + 1 ) − ⌊ a b ⌋ y ( k + 1 ) \begin{aligned} x^{(k)}&=y^{(k+1)}\\ y^{(k)}&=x^{(k+1)}-\lfloor \frac{a}{b}\rfloor y^{(k+1)} \end{aligned} x(k)y(k)=y(k+1)=x(k+1)bay(k+1)
于是就得到了一个递推式,结合边界条件就可以得到解。

void Ex_gcd(int a, int b, int &x, int &y)
{
    if(b == 0)
    {
        x = 1;
        y = 0;
        return;
    }
    int x1, y1;
    Ex_gcd(b, a%b, x1, y1);
    x = y1;
    y = x1-(a/b)*y1;
}

然后求到 x ( 1 ) ,   y ( 1 ) x^{(1)},\ y^{(1)} x(1), y(1),之后可以通过加上若干个 a p + b q = 0 ,   a > 0 a p +b q=0,\ a>0 ap+bq=0, a>0,那么x的最小正整数解就是 x ≡ x ( a ) m o d    p x\equiv x^{(a)}\mod p xx(a)modp

5. 中国剩余定理

韩信点兵:3个人一排剩2个,5个人一排剩3个,7个人一排剩2个,问有几个人?
答案233个或23个 ⋯ \cdots
问题的形式化:
x ≡ a 1 m o d    m 1 x ≡ a 2 m o d    m 2 … x ≡ a k m o d    m k \begin{aligned} x &\equiv a_1 \mod m_1\\ x &\equiv a_2 \mod m_2\\ &\dots\\ x &\equiv a_k \mod m_k \end{aligned} xxxa1modm1a2modm2akmodmk
任意两个 m i ,   m j m_i,\ m_j mi, mj, 需要满足 ( m i , m j ) = 1 (m_i,m_j)=1 (mi,mj)=1

构造一个 M = m 1 m 2 … m k M=m_1m_2\dots m_k M=m1m2mk
再定义一个
M 1 = M m 1 M 2 = M m 2 ⋯ M k = M m k \begin{aligned} M_1&=\frac{M}{m_1}\\ M_2&=\frac{M}{m_2}\\ &\cdots\\ M_k&=\frac{M}{m_k}\\ \end{aligned} M1M2Mk=m1M=m2M=mkM
对于 M i M_i Mi, 可以求一个 t i t_i ti,满足 M i t i ≡ 1 m o d    m i M_i t_i \equiv 1\mod m_i Miti1modmi
这时候就构造出来了! x = ∑ i = 1 k a i t i M i x=\sum_{i=1}^k a_it_iM_i x=i=1kaitiMi
x x x显然是上述同余方程组的解。

其中唯一有问题的就是其中求 t i t_i ti,就是求一个整数a关于p的倒数,现有 ( a , p ) = 1 (a,p)=1 (a,p)=1,
( a ⋅ x ) % p = 1 (a\cdot x)\%p=1 (ax)%p=1可以转化成
a ⋅ x + p ⋅ y = 1 = ( a , p ) a\cdot x+p\cdot y=1=(a,p) ax+py=1=(a,p)
于是就可以用扩展欧几里得算法来求 x x x y y y了,当然我们只需要求 x x x

6. 威尔逊定理

p 是 质 数 ⇔ ( p − 1 ) ! ≡ p − 1 m o d    p p是质数 \Leftrightarrow (p-1)!\equiv p-1 \mod p p(p1)!p1modp
必要性显然
充分性给一个用费马小定理的证明, p ≥ 3 p\geq 3 p3且p是质数:
f ( x ) = ( x − 1 ) ⋅ ( x − 2 ) … ( x − ( p − 1 ) ) = x p − 1 + ( 1 + 2 + ⋯ + p − 1 ) x p − 2 + ⋯ + ( p − 1 ) ! \begin{aligned} f(x)&=(x-1)\cdot (x-2) \dots (x-(p-1)) \\ &=x^{p-1}+(1+2+\dots +p-1)x^{p-2}+\dots+(p-1)! \end{aligned} f(x)=(x1)(x2)(x(p1))=xp1+(1+2++p1)xp2++(p1)!
注意这里满足f(x)=0的根为 1 ∼ ( p − 1 ) 1\sim(p-1) 1(p1)

定义 g ( x ) = x p − 1 − 1 g(x)=x^{p-1}-1 g(x)=xp11
根据费马小定理,满足 g ( x ) ≡ 0 m o d    p g(x) \equiv 0 \mod p g(x)0modp的解也是 1 ∼ ( p − 1 ) 1\sim(p-1) 1(p1)
所以对于任意的 x x x,满足 h ( x ) = f ( x ) − g ( x ) ≡ 0 m o d    p h(x)=f(x)-g(x)\equiv 0 \mod p h(x)=f(x)g(x)0modp

但是考虑到 h ( x ) h(x) h(x)的最高此项是 x ( p − 2 ) x^(p-2) x(p2)这一项,所以方程 h ( x ) ≡ 0 m o d    p h(x)\equiv 0\mod p h(x)0modp最多有 ( p − 2 ) (p-2) (p2)个解,因此 h ( x ) h(x) h(x)只能恒等于0。

所以他的常数项 ( p − 1 ) ! + 1 (p-1)!+1 (p1)!+1必须满足 ( p − 1 ) ! + 1 ≡ 0 m o d    p (p-1)!+1\equiv 0 \mod p (p1)!+10modp,这个式子就是威尔逊定理。
题目:hdu2973

Appendix

施工中 … \dots

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值