数学

数学(更新中

序理论

序理论是利用二元关系来将「次序」这一概念严格化的数学分支,下面将介绍这一分支的基本定义。 ——oi wiki

二元关系

  • 性质:
    1. 自反性
    2. 反自反性
    3. 对称性
    4. 反对称性
    5. 非对称性
    6. 传递性
    7. 连接性
    8. 两基性
    9. 不可比的传递性

偏序集

组合数学

排列数

记为\(A(n, k)\),表示从n个不同元素中取出k个元素进行排列的数目。

基本公式:\(A(n, k)=\frac{n!}{(n-k)!}\)

int A(int n, int k){
    return k ? A(n-1,k-1)*n : 1;
}

实际应用中如果结果需要取模, 那么可以在计算的过程中不断取模以减小数据量。

组合数

记为\(C(n, k)\),表示从n个不同元素中取出k个元素的组合数,不考虑元素的顺序。

基本公式:\(C(n, k)=\frac{n!}{k!\times (n-k)!}\)

实际应用中会利用递推公式\(C(n, k)=C(n-1, k-1) + C(n-1, k)\)计算。

(该公式在n远小于k时尤其有效)

\(k>\frac{n}{2}\)时, 利用\(C(n, k) = C(n, n-k)\)化简。

int C(int n, int k){
    return k ? C(n-1, k-1) + C(n-1, k) : 1;
}

质数(与合数)

定义

一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数;否则称为合数(规定1既不是质数也不是合数)。

性质

基本性质

  • 设a为大于1的正整数,若p是a的大于1的最小正约数则p必为质数。
  • 如果 a 是合数,p 是 a 的最小约数,那么 \(p \le\sqrt{a}\)

分布规律

  • 若n为正整数,在n²到(n+1)² 之间至少有一个质数。

  • 若n为大于或等于2的正整数,在n到n!之间至少有一个质数。

  • 在一个大于1的数a和它的2倍之间(即区间(a, 2a]中)必存在至少一个素数

素数分解(算数基本定理

  • 任何大于1的整数都可以被分解成若干个素数的幂的乘积,且不计素因子的排列顺序时分解方法是唯一的。
  • 把素因子从小到大排列,就得到了标准素数分解式

例如:\(720 = 2^4 \cdot 3^2 \cdot 5^1\)

相关算法

素数判断

bool isprime(int x){
	if(x<=1) return false;
	for(int i=2;i<=sqrt(x);i++){
		if(x%i==0) return false;
	}
	return true;
}

筛素数

  • 埃氏筛法

    该方法时间复杂度\(O(nloglogn)\), 对于某些数字可能会被多次筛选

    例如一个数 24,它会被 2, 3, 4 三个数标记,这就重复了两次,更大的数同理。

//生成不大于 n 的所有质数
bool numlist[100000001];
int prime[20000001], cnt;
void work(int n){
	for(int i=2; i<=n; i++){
		if(numlist[i]==false){
			prime[++cnt] = i ;
			for(int j=i; i*j<=n; j++)
				numlist[i*j] = true;
		}
	}
	return;
}
  • 欧拉筛法

    该方法时间复杂度\(O(n)\), 利用了[素数的基本性质](# 基本性质)。
    简单来说:

    1. 对于一个合数n,可以表示为其最小质因数\(fac_1\)与最大的非自身因数\(fac_2\)的乘积。

      即: 有等式\(n=fac_1\times fac_2\)\(fac_1\)\(fac_2\)使得n唯一,从而避免重复筛选。

    2. 对于每一个\(fac_2\),当其为合数时必然有一最小质因数\(p\)

      1. \(fac_2\)被遍历到时,\(p\)已经在 prime
      2. 在标记\(fac_2 \times p\)后,i%prime[j]==0,退出内层循环。
    bool numlist[100000001];
    int prime[20000001], cnt;
    void work(int n){
    	for(int i=2; i<=n; i++){
    		if(numlist[i]==false)
    			prime[++cnt] = i ;
    		for(int j=1; j<=cnt&&i*prime[j]<=n; j++){
    			numlist[i*prime[j]] = true ;
    			if(i%prime[j]==0)
    				break;
    		} 
    	}
    	return;
    }
    

gcd和lcm

常见算法

对于两数m和n,计算最大公因数常利用辗转相除法,最小公倍数则用算式\(m\times n \div gcd(m,n)\)计算。

int gcd(int m, int n){
    return n ? m : gcd(n, m%n);
}
int lcm(int m,int n){
    return m*n/gcd(m,n);
}

相互关系

四者关系可以从因数分解([素数分解](# 素数分解))的角度来理解。

对于m和n有:

\[m = 2^{a_1} \times 3^{a_2} \times 5^{a_3} \times \cdots\cdots \\ n = 2^{b_1} \times 3^{b_2} \times 5^{b_3} \times \cdots\cdots \]

可注意到:

  • gcd必须能同时整除a和b,所以每个素数的指数不能超过a和b中对应素数的最小指数。
  • 而lcm需要同时被a和b整除,所以每个素数的指数必须至少等于a和b中的最大指数。

那么对于gcd和lcm有:

\[gcd = 2^{min(a_1,b_1)} \times 3^{min(a_2,b_2)} \times 5^{min(a_3,b_3)} \times \cdots\\ lcm = 2^{max(a_1,b_1)} \times 3^{max(a_2,b_2)} \times 5^{max(a_3,b_3)} \times \cdots \]

于是能得到:

\[m \times n = gcd \times lcm \]

当然,这个结论不是重点,重点是对于该推导方法的运用:P1029

posted @ 2025-02-16 16:50  yangzwww  阅读(28)  评论(0)    收藏  举报