算法数论笔记


数论

数论都是针对整数而言

倍数、因数、整除

对于整数 a 、 b a、b ab,存在整数 q q q满足a=bq

则称 a a a b b b的倍数、 b b b a a a的因数、 b ∣ a b|a ba

最大公因数 记作: g c d ( a , b ) gcd(a,b) gcda,b 或者 ( a , b ) (a,b) a,b

最大的 d d d满足 d ∣ a d | a da d ∣ b d | b db

求最大公因数=>辗转相除法

a , b , c a, b, c a,b,c是任意三个不全为0的整数,满足存在整数 q q q a = b q + c a = bq+ c a=bq+c,那么 ( a , b ) = ( b , c ) (a, b)= (b, c) (a,b)=(b,c)

代码如下 时间复杂度 O ( l o g ( m i n ( a , b ) ) ) O(log(min(a,b))) O(log(min(ab)))

int gcd(int a,int b)
{
    return b ? gcd(b,a%b) : a ;
}

扩展欧几里得

a , b a, b a,b是任意两个不全为 0 0 0的整数,则存在整数 x , y x,y x,y
使得 a x + b y = ( a , b ) ax+ by =(a,b) ax+by=(a,b)

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

注意

  1. 满足 a x + b y = ( a , b ) ax+by = (a, b) axby=(a,b) ( x , y ) (x,y) (x,y)有无限多组,假设 ( x 0 , y 0 ) (x_0, y_0) (x0,y0)是其中一组,则所有解为: ( x 0 + k b ( a , b ) , y 0 − k a ( a , b ) ) , ( k ∈ Z ) (x_0+k\frac{b}{(a,b)},y_0-k\frac{a}{(a,b)}),(k\in Z) (x0+k(a,b)b,y0k(a,b)a),(kZ)

    口诀 : 前加后减,k倍相反除 g c d gcd gcd

  2. a x + b y = 1    ⟺    ( a , b ) = 1 ax+by=1 \iff (a,b)=1 ax+by=1(a,b)=1

stein算法(求超过 l o n g l o n g longlong longlong范围的最大公因数)

  • 如果 a = 0 a=0 a=0 b = 0 b =0 b=0,则 ( 0 , b ) = b , ( a , 0 ) = a (0, b) = b, ( a,0) = a (0,b)=b,(a,0)=a ()

  • 如果 a , b a, b a,b 都是偶数,则 ( a , b ) = ( a / 2 , b / 2 ) (a,b)= (a/2,b/2) (a,b)=(a/2,b/2)

  • 如果 a a a是偶数,b是奇数,则 ( a , b ) = ( a / 2 , b ) (a, b)= (a/2,b) (a,b)=(a/2,b)

  • 如果 a a a是奇数,b是偶数,则 ( a , b ) = ( a , b / 2 ) (a, b)= (a, b/2) (a,b)=(a,b/2)

  • 如果 a , b a,b ab都是奇数,不妨设 a > b a>b a>b,则 ( a , b ) = ( b , a − b ) (a,b)=(b,a-b) (ab)=(bab)

    总结:为0等于其他,偶数除2,奇数取模变相减

**最小公倍数 **

记作: l c m ( a , b ) lcm(a,b) lcm(a,b) 或者 [a,b]

最小的 m m m满足 a ∣ m a|m am 和 b|m

两个数相乘除最大公因数

int lcm(int a, int b)
{ 
	return a / gcd(a, b) * b; //这里是为了防止溢出 先除后乘
}

互质

两个整数最大公因数是 1 1 1 g c d ( a , b ) = 1 gcd(a,b)=1 gcd(a,b)=1

具有的性质 a、b互质 a| bc 则 a | c

质数(素数)、合数

设p为正整数,p >1,如果p 的正因数只有1及它本身,则称p为质数(素数),否则称p为合数。

算数基本定理

任意大于1的整数a能够唯一写成 a = p 1 α 1 p 2 α 2 . . . p k α k a={p_1}^{\alpha_1}{p_2}^{\alpha_2}...{p_k}^{\alpha_k} a=p1α1p2α2...pkαk ,其中 p i p_i pi是质数,

α 1 > 0 , i = 1.. k \alpha_1>0,i=1..k α1>0,i=1..k,且 p i < p j ( i < j ) p_i<p_j(i<j) pi<pj(i<j)

埃氏筛法

用质数把质数的倍数筛掉

代码如下 时间复杂度 O ( n l o g ( l o g ( n ) ) ) O(nlog(log(n))) O(nlog(log(n)))非常接近 O ( n ) O(n) O(n)

int pr[N],cnt;
bool st[N]; //st[i] 表示i不是质数
void get_pr(int n)
{
    for(int i=2;i<=n;i++)
    {
        if(st[i]) continue; //如果这个数不是质数跳过
        pr[cnt++]=i; //是的话加入质数数中
        for(int j=i+i;j<=n;j+=i) st[j]=true; //用这个质数筛其他数
    }
}

欧拉筛

每个合数只需被其最小质因子筛掉

代码如下 时间复杂度 O ( n ) O(n) O(n)

int pr[N],cnt;
bool st[N];

for(int i=2;i<=n;i++)
{
    if(!st[i]) pr[cnt++]=i;//如果这个数是质数
    for(int j=0;pr[j]<=n/i;j++)
    {
        st[pr[j]*i]=true;
        if(i%pr[j]==0) break;
    }
}

证明:

假设要筛的数为 x x x x = p 1 α 1 p 2 α 2 . . . p k α k x={p_1}^{\alpha_1}{p_2}^{\alpha_2}...{p_k}^{\alpha_k} x=p1α1p2α2...pkαk

当枚举到质数$ p_1$ 时候 i = p 1 α 1 − 1 p 2 α 2 . . . p k α k i={p_1}^{\alpha_1-1}{p_2}^{\alpha_2}...{p_k}^{\alpha_k} i=p1α11p2α2...pkαk

当枚举到质数$ p_2$ 时候 i = p 1 α 1 p 2 α 2 − 1 . . . p k α k i={p_1}^{\alpha_1}{p_2}^{\alpha_2-1}...{p_k}^{\alpha_k} i=p1α1p2α21...pkαk 但是当 i % p r [ j ] = = 0 i\%pr[j]==0 i%pr[j]==0 就break掉了不可能存在这种情况 所以只会被最小质因子筛掉

质因数分解

求一个数n的所有因数

vector<int> fac;
for(int i=1;i<=n/i;i++)
{
    if(n%i==0)
    {
        fac.push_back(i);
        if(n/i != i) fac.push_back(n/i);
        
    }
}

求一个数n的所有质因数

vector<int> pfac;
for(int i=1;i<=n/i;i++)
{
    if(n%i==0)
    {
        pfac.push_back(i);
        while(n%i==0) n/=i;
    }
}
if(n>1) pfac.push_back(n)//上面把所有小于等于根号n的质因子筛掉了 
    //最多剩下一个大于根号n的质因子

同余

a , b , m a, b, m a,b,m为三个整数,其中 m m m >0,如果满足 a % m = b % m a\%m = b\%m a%m=b%m,则称a与b对模m同余,记作 a ≡ b ( m o d m ) a\equiv b (mod m) ab(modm)

等价类

令集合 i = { x ∣ x ≡ i ( m o d    m ) } i = \{x | x \equiv i (\mod m) \} i={xxi(modm)} , ( i ∈ Z ) (i \in \mathbb{Z}) (iZ)

假设 j = i + m j=i+m j=i+m,则 j = i j=i j=i

等价类上的运算

Z m = 0 , 1 , . . . , m − 1 \mathbb{Z}_m={0,1,...,m-1} Zm=0,1,...,m1上定义两种运算 + , × +,× +,×,其中

A + B = C A+B=C A+B=C当且仅当 ∀ a ∈ A , b ∈ B , a + b ∈ C \forall a \in A,b \in B,a+b \in C aA,bB,a+bC

A × B = C A×B=C A×B=C 当且仅当 ∀ a ∈ A , b ∈ B , a × b ∈ C \forall a \in A,b \in B,a×b \in C aA,bB,a×bC

逆元

如果 a , b ∈ Z m a,b \in \mathbb{Z}_m a,bZm,满足 a b = 1 ab=1 ab=1,则称 b b b a a a的逆元,记作 a − 1 a^{-1} a1

判定在 Z m \mathbb{Z}_m Zm里,a是否有逆元 如果有,如何求 a − 1 a^{-1} a1

  • a b = k m + 1 ab=km+1 ab=km+1 ,扩展欧几里得算法
  • a a a Z m \mathbb{Z}_m Zm内有逆元,当且仅当 ( a , m ) = 1 (a, m)= 1 (a,m)=1
  • 如果 m m m为质数,则任意 0 < a < m 0<a<m 0<a<m a ∈ Z m a∈\mathbb{Z}_m aZm有逆.

欧拉函数

定义欧拉函数 φ ( n ) \varphi (n) φ(n)为正整数 n n n与序列 1 , 2 , . . . , n − 1 1,2,..., n - 1 1,2,...,n1, n n n中互质的数的个数

求欧拉函数

n = p 1 α 1 p 2 α 2 . . . p k α k n={p_1}^{\alpha_1}{p_2}^{\alpha_2}...{p_k}^{\alpha_k} n=p1α1p2α2...pkαk ,则 φ ( n ) = ( p 1 − 1 ) p 1 α 1 − 1 ( p 2 − 1 ) p 2 α 2 − 1 . . . ( p k − 1 ) p k α k − 1 \varphi (n)=(p_1-1){p_1}^{\alpha_1-1}(p_2-1){p_2}^{\alpha_2-1}...(p_k-1){p_k}^{\alpha_k-1} φ(n)=(p11)p1α11(p21)p2α21...(pk1)pkαk1

ll get_phi(int n)
{
	ll phi =1;
	for(int i=2;i<=n/i;i++)
	{
		if(n%i==0)
		{
			phi *= (i-1);
			n/=i;
			while(n%i==0) phi *=i,n/=i;
		}
	}
	if(n>1) phi*=n;
	return phi;
}

φ ( 1 ) . . φ ( n ) \varphi (1)..\varphi (n) φ(1)..φ(n) 欧拉筛的基础上做修改

int pr[N],cnt;
int phi[N];
bool st[N];

for(int i=2;i<=n;i++)
{
    if(!st[i]) pr[cnt++]=i;phi[i]=i-1//如果这个数是质数
    for(int j=0;pr[j]<=n/i;j++)
    {
        st[pr[j]*i]=true;
        if(i%pr[j]==0) 
        {
        	phi[i*pr[j]]=phi[i]*pr[j];
        	break;
        }
        phi[i*pr[j]] = phi[i]*(pr[j]-1);
    }
}

欧拉定理

如果 ( a , m ) = 1 ( a, m)=1 (a,m)=1,那么 a φ ( m ) = 1 ( m o d    m ) a^{\varphi (m)}=1 (\mod m) aφ(m)=1(modm)

扩展欧拉定理

a c = a c % φ ( m ) + φ ( m ) ( m o d    m ) a^c=a^{c\%\varphi (m)+\varphi (m)} (\mod m) ac=ac%φ(m)+φ(m)(modm) c > = φ ( m ) c>=\varphi (m) c>=φ(m)

费马小定理

p p p为质数,如果 p × a p × a p×a,那么 a P − 1 = 1 ( m o d p ) a^{P-1}=1 (mod p) aP1=1(modp)

m m m为正整数, a ∈ Z m , ( a , m ) = 1 a ∈ \mathbb{Z}_m,(a,m)= 1 aZm,(a,m)=1,逆元 a − 1 = a φ ( m ) − 1 a^{-1} =a^{\varphi (m)}-1 a1=aφ(m)1

设p为质数, a ∈ Z p , 0 < a < p , a ∈ \mathbb{Z}_p,0<a<p, aZp,0<a<p逆元 a − 1 = a p − 2 a^{-1} = a^{p-2} a1=ap2

同余方程组

m 1 , m 2 , . . , m k m_1,m_2,..,m_k m1,m2,..,mk是两两互质的 k k k个正整数,求方程组 { x ≡ a 1 ( m o d    m 1 ) x ≡ a 2 ( m o d    m 2 ) . . x ≡ a k ( m o d    m k ) \left\{ \begin{aligned} &x \equiv a_1(\mod m_1)\\ &x \equiv a_2(\mod m_2)\\.\\.\\&x \equiv a_k(\mod m_k)\\ \end{aligned} \right. ..xa1(modm1)xa2(modm2)xak(modmk) 的解 x x x

先假设 k = 2 k=2 k=2的情况下 x = y 1 m 1 + a 1 = y 2 m 2 + a 2 x=y_1m_1 +a_1=y_2m_2 + a_2 x=y1m1+a1=y2m2+a2

根据扩展欧几里得可得 x = x 0 + k m 1 m 2 [ m 1 , m 2 ] x=x_0+k \frac{m_1m_2}{[m_1,m_2]} x=x0+k[m1,m2]m1m2

有解当且仅当 ( m 1 , m 2 ) ∣ a 1 − a 2 (m_1,m_2)|a_1-a_2 (m1,m2)a1a2

解的形式为 x ≡ x 0 m o d    [ m 1 , m 2 ] x \equiv x_0 \mod [m_1,m_2] xx0mod[m1,m2]

然后每两项合并, x ≡ x 0 m o d    [ m 1 , m 2 . . m k ] x \equiv x_0 \mod [m_1,m_2..m_k] xx0mod[m1,m2..mk]

中国剩余定理(孙子定理)

x ≡ ∑ i = 1 k M i − 1 M i a i ( m o d    M ) x\equiv \sum_{i=1}^k{M_i}^{-1}M_i a_i(\mod M) xi=1kMi1Miai(modM)

其中 M = m 1 m 2 . . m k , M i = M / m i M=m_1 m_2..m_k,M_i=M/m_i M=m1m2..mk,Mi=M/mi

计数问题解决方法

  • 直接计算
  • dp
  • 容斥
  • 生成函数
  • 其他的定理

加法原理和乘法原理

加法原理:做某件事情有几种选择,每种选择的方案数之和就是做这件事情的方案数

乘法原理:做某件事情分为几步,每步的方案数是独立的,则它们的积就是做这件事情的方案数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值