数论
最大公约数
欧几里得算法求gcd
\(设 a > b, 且a = b × q + r,r < b\)
\(则\textit{gcd(a, b) = gcd(b, a % b)}\)
code
int gcd(int a, int b)
{
return !b ? a : gcd(b, a % b);
}
扩展欧几里得算法(exgcd)
常用于求 \(ax + by = gcd(a, b)\) 的一组可行解
code
int exgcd(int a, int b, int &x, int &y)
{
if (!b)
{
x = 1, y = 0;
return a;
}
int d = exgcd(b, a % b, y, x);
y -= a / b * x;
return d;
}
组合数
- 定义:从 \(n\) 个不同元素中,任取 \(m(m≤n)\) 个元素并成一组,叫做从 \(n\) 个不同元素中取出 \(m\) 个元素的一个组合;从 \(n\) 个不同元素中取出 \(m(m≤n)\) 个元素的所有组合的个数,叫做从 \(n\) 个不同元素中取出 \(m\) 个元素的组合数.
- 公式: \(C_{n}^{m}=\frac{n!}{m!(n - m)!}\)
递推求组合数
code
for (int i = 0; i <= n; i ++ )
{
c[i][i] = c[i][0] = 1;
for (int j = 1; j < i; j ++ )
c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod;
}
Lucas定理求组合数
\(\textit{C(n,m)%p=C(n/p,m/p)*C(n%p,m%p)%p}\)
\((p为质数)\)
code1
int qmi(int a, int k)
{
int res = 1;
while (k)
{
if (k & 1) res = (ll) res * a % mod;
a = (ll) a * a % mod;
k >>= 1;
}
return res;
}
int C(int a, int b)
{
int res = 1;
for (int i = 1, j = a; i <= b; i ++, j -- )
{
res = (ll) res * j % mod;
res = (ll) res * qmi(i, mod - 2) % mod;
}
return res;
}
int lucas(ll a, ll b)
{
if (a < mod && b < mod) return C(a, b);
return (ll)C(a % mod, b % mod) * lucas(a / mod, b / mod) % mod;
}
code2
int qmi(int a, int k)
{
int res = 1;
while (k)
{
if (k & 1) res = (ll) res * a % mod;
a = (ll) a * a % mod;
k >>= 1;
}
return res;
}
void init()
{
c[0] = 1;
for (int i = 1; i <= n; i ++ )
c[i] = c[i - 1] * i % mod;
}
int C(int a, int b)
{
return c[a] * qmi(c[b] * c[a - b] % mod, mod - 2) % mod;
}
int lucas(ll a, ll b)
{
if (a < mod && b < mod) return C(a, b);
return (ll)C(a % mod, b % mod) * lucas(a / mod, b / mod) % mod;
}
同余
中国剩余定理 CRT
求解如下形式的一元线性同余方程组(其中 \(n_1, n_2, ···, n_k\) 两两互质)
\(
\left\{
\begin{matrix}
x & \equiv & a_1 & (mod \ n_1)\\
x & \equiv & a_2 & (mod \ n_2)\\
\vdots\\
x & \equiv & a_k & (mod \ n_k)
\end{matrix}
\right.
\)
code
int CRT(int k, int *a, int *r)
{
int M = 1, ans = 0;
for (int i = 1; i <= k; i ++ ) M = M * r[i];
for (int i = 1; i <= k; i ++ )
{
int m = M / r[i], b, y;
exgcd(m, r[i], b, y);
ans = (ans + a[i] * m * b % M) % M;
}
return (ans % M + M) % M;
}
拓展中国剩余定理 exCRT
质数
- 质数:只有两个正因数(1和自己)的自然数即为质数.比1大但不是素数的数称为合数.1和0既非素数也非合数.
性质
- \(N\) 以内的素数的个数随着N的增大趋近于 \(log(n)\).
- 从不大于 \(n\) 的自然数随机选一个数,它是素数的概率大约是 \(1/In n\)(素数定理).
- 随着 \(n\) 的增大素数越来越稀疏.
- 在一个大于 \(1\) 的数 \(a\) 和它的2倍之间(即区间 \((a,2a]\) 中)必存在至少 \(1\) 个素数.
线性筛(欧拉筛法)
code
int primes[N], cnt;
bool st[N];
void prime(int n)
{
for (int i = 2; i <= n; i ++ )
{
if (!st[i]) primes[ ++ cnt] = i;
for (int j = 1; j <= cnt && primes[j] * i <= n; j ++ )
{
st[primes[j] * i] = true;
if (i % primes[j] == 0) break;
}
}
}
欧拉定理 & 费马小定理
欧拉函数
定义
欧拉函数,即 \(\varphi(n)\),表示的是小于等于 \(n\) 和 \(n\) 互质的数的个数。
性质
-
欧拉函数是积性函数。
-
特别地,当 n 是奇数时 \(\varphi(2n) = \varphi(n)\)。
-
\(n = \sum_{d \mid n}{\varphi(d)}\)。
-
若 \(n = p^k\),其中 \(p\) 是质数,那么 \(\varphi(n) = p^k - p^{k - 1}\)。 (根据定义可知)
-
由唯一分解定理,设
n = \(\prod_{i=1}^{s}p_i^{k_i}\),其中 \(p_i\) 是质数,有
\(\varphi(n) = n \times \prod_{i = 1}^s{\dfrac{p_i - 1}{p_i}}\)。
求欧拉函数
code
int phi(int x)
{
if (x == 1) return 1;
int res = x;
for (int i = 2; i * i <= x; i ++ )
{
if (x % i != 0) continue;
while (x % i == 0)
x /= i;
res = res / i * (i - 1);
}
if (x != 1) res = res / x * (x - 1);
return res;
}
线性筛欧拉函数
code
const int N = 3e8;
int primes[N], cnt;
bool st[N];
int phi[N];
void prime_phi(int n)
{
phi[1] = 1;
for (int i = 2; i <= n; i ++ )
{
if (!st[i])
{
primes[ ++ cnt] = i;
phi[i] = i - 1;
}
for (int j = 1; primes[j] * i <= n && j <= cnt; j ++ )
{
st[primes[j] * i] = true;
if (i % primes[j] == 0)
{
phi[primes[j] * i] = phi[i] * primes[j];
break;
}
phi[primes[j] * i] = phi[i] * (primes[j] - 1);
}
}
}
欧拉定理
定义
若 \(\gcd(a, m) = 1\),则 \(a^{\varphi(m)} \equiv 1 \pmod{m}\)。
扩展欧拉定理
定义
\( a^b \equiv \begin{cases} a^{b \bmod \varphi(m)}, &\gcd(a,m) = 1, \\ a^b, &\gcd(a,m)\ne 1, b < \varphi(m), \\ a^{(b \bmod \varphi(m)) + \varphi(m)}, &\gcd(a,m)\ne 1, b \ge \varphi(m). \end{cases} \pmod m\)
- 解释
第二行表达的意思是:如果 \(b < \varphi(m)\) 的话,就不能降幂了。
原因是因为题目中 \(m\) 不会太大,而如果 \(b < \varphi(m)\),自然复杂度是可以接受的。而如果 \(b \ge \varphi(m)\) 的话,复杂度可能就超出预期了,这个时候我们才需要降幂来降低复杂度。
费马小定理
定义
若 \(p\) 为素数,\(\gcd(a, p) = 1\),则 \(a^{p - 1} \equiv 1 \pmod{p}\)。
另一个形式:对于任意整数 \(a\),有 \(a^p \equiv a \pmod{p}\)。
高斯消元
code
const int N = 80;
const db eps = 1e-6;
int n;
db gs[N][N];
void gauss()
{
for (int i = 0; i < n; i++)
{
int pos = i;
for (int j = i + 1; j < n; j++)
if (fabs(gs[j][i]) > fabs(gs[pos][i]))
pos = j;
swap(gs[i], gs[pos]);
for (int j = 0; j < n; j++)
{
if (i == j)
continue;
double div = gs[j][i] / gs[i][i];
for (int k = i; k <= n; k++)
gs[j][k] -= gs[i][k] * div;
}
}
for (int i = 0; i < n; i++)
gs[i][n] /= gs[i][i];
}
数论函数
积性函数
若有一函数 \(f\), 对于 \(\forall x, y \in S\) 使得 \(x \times y \in S, f(x)f(y) = f(xy)\), 则称 \(f\) 在 \(S\) 下 具有积性,也称 \(f\) 为 \(S\) 下的 积性函数.
定义
-
完全积性函数:若函数 \(f\) 在实数域 \(R\) 下具有积性,则我们称 \(f\) 具有 完全积性,称 \(f\) 为 完全积性函数.完全积性函数属于积性函数.
-
不完全积性函数 :若有一函数 \(f\) , 不存在集合 \(S\) 使得 \(f\) 为 \(S\) 下的积性函数,但存在二元组 \(<x, y>\) 使得
\(f ( x ) f ( y ) = f ( x y )\) 成立,则我们称 \(f\) 为不完全积性函数.
不完全积性函数不属于积性函数. -
性质:若 \(f, g\) 均为积性函数,则 \(f\cdot g\) 也是积性函数.
数论函数
- 指示函数: \(I(x) = 1\), 具有完全积性.
- 幂函数: \(Id_k(n) = n^k\), 具有完全积性.
- 单位函数 : \(\varepsilon(x) = [x == 1]\) , 整数域下有积性.
- 莫比乌斯函数: \(\mu(x)\), \(\mu \times I = \varepsilon\).
- 欧拉函数 : \(\varphi(x)\)小于 \(x\) 并与 \(x\) 互质的数的个数.
- 除数函数: \(\sigma_k(x) = \sum _{d|n}d^k\), 当 \(k = 1\) 时为因数和函数 \(\sigma(x)\) , 当 \(k = 0\) 时为因数个数函数 \(\sigma_0(x)\).
迪利克雷(Dirichlet)卷积
一种二元运算,定义为:
\((f\times g)(n) = \sum_{xy=n} f(x)g(y)\)
等价于
\((f\times g)(n) = \sum_{d|n} f(d)g(\frac{n}{d})\)
性质
1、交换律:\((f\times g)(x) = (g\times f)(x)\).
2、结合律:\((f\times g \times h)(x) = (f \times (g \times h))(x)\).
3、加法分配律:\(((f + g) \times h)(x) = (f \times h + g \times h)(x)\)
4、单位元:\((\varepsilon \times f)(n) = \sum _{d|n}\varepsilon(d)f(\frac{n}{d}) = f(n)\) (注意仅在 \(d=1\) 时 \(\varepsilon (n)\) 不等于 \(0\)).
所以单位函数 \(\varepsilon\) 是狄利克雷卷积的单位元.
5、逆元 :假设 \(f \times g = \varepsilon\) , 则称 \(g\) 是 \(f\) 的迪利克雷逆元(Dirichlet inverse), 记作 \(f^{-1}\) ,必要条件为 \(f(1)\ne 0\).
对于 \(g = f^{-1}\) 的一个递归定义如下:
\(g(n) = \left\{\begin{matrix}\frac{1}{f(n)}, &n=1 \\-\frac{1}{f(1)}\sum _{d|n,d>1} f(d)g(\frac{n}{d}),&n \ne 1\end{matrix}\right.\)
莫比乌斯反演
矩阵
矩阵快速幂
code
struct Matrix
{
int a[N][N];
Matrix()
{
memset(a, 0, sizeof a);
}
Matrix operator * (const Matrix &b) const
{
Matrix res;
int r;
for (int i = 1; i <= n; i ++)
for (int k = 1; k <= n; k ++ )
{
r = a[i][k];
for (int j = 1; j <= n; j ++ )
res.a[i][j] = (res.a[i][j] + r * b.a[k][j]) % mod;
}
return res;
}
}ans, base;
void qmi(int k)
{
while (k)
{
if (k & 1) ans = ans * base;
base = base * base;
k >>= 1;
}
}

浙公网安备 33010602011771号