title: 数论
tags: [数论]
categories: [OI, 个人整理]

公约数

数论

欧几里得算法

为了解决最大公约数。

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

质数

暴力筛

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

埃氏筛

int p[];
void primes(){
	for (int i=2;i<=N;i++){
		if (!p[i]){
			for (int j = i;j<=N;j+=i){
				p[j] = i; // 可以用来质因数分解
			}
		}
	}
}

欧拉筛

bool notPrime[N];  
vector <int> p;  
void prime(int n){    
    notPrime[1] = 1;
    for (int i=2;i<=n;i++){  
        if (!notPrime[i]) p.push_back(i);  
        for (int u:p){  
            if (u * i > n) break;  
            notPrime[u * i] = 1;  
            if (i % u == 0) break;  
        }  
    }  
}

分解质因数

vector <int> v;
void fenjie(int n){
	for(int i=2;i*i<=n;i++){
		while (n%i==0){
			n/=i;
			v.push_back(i);
			n/=i;
		}
	}
	if (n > 1) v.push_back(n);
}

逆元

费马小定理

如果要计算 a / b % m 。要计算除以b在模m意义下的逆元。
两个条件:

  • gcd(b,m) = 1
  • m是质数
    inv b = pow(b,m-2) % m

连续数字逆元的线性递推

证明太巧妙了!
根据带余除法,有 \(p\equiv q\times i+r(\bmod p)\) ,\(r < q\)
因为 \(p\equiv0(\bmod p)\),所以 \(0\equiv q\times i+r(\bmod p)\)
变形得 \(r\equiv -q\times i(bmod p)\)
等式两边\(\times inv_i\) ,得 \(r\times inv_i\equiv p-q(\bmod p)\)
等式两边\(\times inv_r\) ,得\(inv_i \equiv inv_r \times(p-q) (\bmod p)\)
故而得:\(inv_i \equiv inv_{p\bmod i}\times(p-p/i) (\bmod p)\)

连续阶乘逆元的线性递推

这个就相对好理解了。

inv[n] = b;
inv[i] = (i + 1) * inv[i + 1] % MOD;