文章目录
数论
数论都是针对整数而言
倍数、因数、整除
对于整数 a 、 b a、b a、b,存在整数 q q q满足a=bq
则称 a a a是 b b b的倍数、 b b b是 a a a的因数、 b ∣ a b|a b∣a
最大公因数 记作: g c d ( a , b ) gcd(a,b) gcd(a,b) 或者 ( a , b ) (a,b) (a,b)
最大的 d d d满足 d ∣ a d | a d∣a和 d ∣ b d | b d∣b
求最大公因数=>辗转相除法
设 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(a,b)))
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
}
注意:
-
满足 a x + b y = ( a , b ) ax+by = (a, b) ax+by=(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,y0−k(a,b)a),(k∈Z)
口诀 : 前加后减,k倍相反除 g c d gcd gcd
-
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 a,b都是奇数,不妨设 a > b a>b a>b,则 ( a , b ) = ( b , a − b ) (a,b)=(b,a-b) (a,b)=(b,a−b)
总结:为0等于其他,偶数除2,奇数取模变相减
**最小公倍数 **
记作: l c m ( a , b ) lcm(a,b) lcm(a,b) 或者 [a,b]
最小的 m m m满足 a ∣ m a|m a∣m 和 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α1−1p2α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α2−1...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) a≡b(modm)。
等价类
令集合 i = { x ∣ x ≡ i ( m o d m ) } i = \{x | x \equiv i (\mod m) \} i={x∣x≡i(modm)} , ( i ∈ Z ) (i \in \mathbb{Z}) (i∈Z)
假设 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,...,m−1上定义两种运算 + , × +,× +,×,其中
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 ∀a∈A,b∈B,a+b∈C
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 ∀a∈A,b∈B,a×b∈C
逆元
如果 a , b ∈ Z m a,b \in \mathbb{Z}_m a,b∈Zm,满足 a b = 1 ab=1 ab=1,则称 b b b是 a a a的逆元,记作 a − 1 a^{-1} a−1
判定在 Z m \mathbb{Z}_m Zm里,a是否有逆元 如果有,如何求 a − 1 a^{-1} a−1
- 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 a∈Zm有逆.
欧拉函数
定义欧拉函数 φ ( n ) \varphi (n) φ(n)为正整数 n n n与序列 1 , 2 , . . . , n − 1 1,2,..., n - 1 1,2,...,n−1, 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)=(p1−1)p1α1−1(p2−1)p2α2−1...(pk−1)pkαk−1
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) aP−1=1(modp)。
设 m m m为正整数, a ∈ Z m , ( a , m ) = 1 a ∈ \mathbb{Z}_m,(a,m)= 1 a∈Zm,(a,m)=1,逆元 a − 1 = a φ ( m ) − 1 a^{-1} =a^{\varphi (m)}-1 a−1=aφ(m)−1
设p为质数, a ∈ Z p , 0 < a < p , a ∈ \mathbb{Z}_p,0<a<p, a∈Zp,0<a<p,逆元 a − 1 = a p − 2 a^{-1} = a^{p-2} a−1=ap−2
同余方程组
设 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. ⎩⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎧..x≡a1(modm1)x≡a2(modm2)x≡ak(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)∣a1−a2
解的形式为 x ≡ x 0 m o d [ m 1 , m 2 ] x \equiv x_0 \mod [m_1,m_2] x≡x0mod[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] x≡x0mod[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) x≡∑i=1kMi−1Miai(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
- 容斥
- 生成函数
- 其他的定理
加法原理和乘法原理
加法原理:做某件事情有几种选择,每种选择的方案数之和就是做这件事情的方案数
乘法原理:做某件事情分为几步,每步的方案数是独立的,则它们的积就是做这件事情的方案数