找了一些曾经没提到的算法。这应该是数学基础系最后一篇。
曾经的文章:
数学基础I
莫比乌斯反演I
莫比乌斯反演II
数学基础II
生成函数
数学基础III
博弈论
容斥原理(hidden)
线性基(hidden)
卡特兰数/第二类斯特林数(hidden)
置换群(hidden)
莫比乌斯反演III(hidden)
线性筛(hidden)
欧拉函数
计算单个欧拉函数
设\(n\)的唯一分解为\(p_i\),则\(\varphi(n)=n\prod(1-\frac{1}{p_i})\)。
奇偶性
\(2|\varphi(n)\Leftrightarrow n \ne 2\)
约数拆分
\[\varphi(pq)=\frac{\varphi(p)\varphi(q)\gcd(p,q)}{\varphi(\gcd(p,q))}\]
其它性质
- 比\(n\)小的与\(n\)互质的数的和为\(n\cdot \frac{\varphi(n)}{2}\)
证明:满足条件的数是成对出现的,可分为\(\frac{\varphi(n)}{2}\)组,每组和为\(n\)。 - 等式二:\(\sum_{d|n}\varphi(d)=n\)
- 定义变换:\(\sum_{i=1}^n[(i,n)=1]=\varphi(n)\)
和莫比乌斯函数换一换可以得到等式三。
练习题
求\(\sum_{i=1}^n\sum_{j=1}^nisprime((i,j))\)。
好像与各种恒等变形有关的题都可以叫莫比乌斯反演……
与抽取变换类似,把质数提到前面,有\[=\sum_{p=prime[]}\sum_{i=1}^n\sum_{j=1}^n[(i,j)=p]\]
\[=\sum_{p=prime[]}\sum_{i=1}^{\lfloor\frac{n}{p}\rfloor}\sum_{j=1}^{\lfloor\frac{n}{p}\rfloor}[(i,j)=1]\]
预处理欧拉函数前缀和,枚举质数即可。复杂度\(O(\ln n)\)。
Miller-Rabin质数测试
对于一个数\(n\),将\(n-1\)分解为\(u\times 2^t(2\nmid u)\)。然后我们随机一个\(a=random(1,n-1)\),每次再枚举\(2\)的次数\(k\)。若\(a^{u\times 2^k}=1\),且\(a^{u\times 2^{k-1}}\ne1\)且\(a^{u\times 2^{k-1}}\ne n-1\),那么\(n\)不是质数(二次探测定理)。最后若\(a^{u\times 2^t}\ne1\),则\(n\)不是质数(费马小定理),否则\(n\)可能是质数。可以证明每次判断可能是质数的正确率是75%,因此我们随机20次即可。此时错误率为\(10^{-14}\)。
证明见各大博客。
inline int miller_rabin(long long n) {
if(n == 2) return 1;
if(n < 2 || !(n&1)) return 0;
long long t = 0, u = n-1;
while(u&1) {
t++;
u >>= 1;
}
for(int ri; ri < 20; ri++) {
long long a = rand() % (n-1) + 1, last = qpow(a, u, n);
for(int i = 0; i < t; i++) {
long long x = qmul(last, last, n);
if(x == 1 && last != 1 && last != n-1) return 0;
last = x;
}
if(last != 1) return 0;
}
return 1;
}
2018.10.1UPD:事实证明只用随机8次即可通过\(10^5\)以上的测试数量。这说明每次判断的正确率可能高于95%。注意可以加上前10个质数的特判。
Pollard's rho算法
没用的东西
生日悖论 在\([1,n]\)中随机撒点,期望第一次取到重点的次数是\(\sqrt n\)。
我们首先考虑这样一个算法:在\([2,n-1]\)中随机选取\(k\)个数,若其中有两个数的差与\(n\)不互质,则这个差与\(n\)的最小公倍数是\(n\)的一个约数。
可以证明\(k\)取约\(n^{\frac{1}{4}}\)时有较大概率得到答案。这样复杂度太高。
考虑不生成随机数,改为每次检查两个相邻的数。我们希望这样能得到答案。
设\(x_0=rand()\),每次令\(x=(x_0^2+a)\bmod n\),然后检查\(\gcd(|x-x_0|,n)\)是否为\(1\)。
正文
但是这样会出现循环,即\(x\)又取到了一个之前取过的值。于是我们取\(y=x_1,x_2,x_4,x_8...\)即可,当\(\gcd(|x-y|,n)\in [2,n-1]\)时找到一个约数,当\(x=y\)时重新选一个\(a\)再次进行这个算法。
设\(n\)的一个小约数是\(p\),可以证明找到这个约数的期望时间复杂度为\(O(\sqrt p)\)。
为了提高效率,我们递归求解,每次先用Miller-Rabin判断是否为质数,然后分解。若出现循环则再次调用(此时\(a\)不同),否则递归处理\(p\)和\(\frac{n}{p}\)。
inline long long pollard_rho(long long n, long long a) {
long long i = 1, k = 2, x = rand()%n, y = x;
for(;;) {
i++;
x = (mul(x, x) + a) % n;
long long d = gcd(abs(x-y), n);
if(d != 1 && d != n) return d;
if(x == y) return n; // 返回不可行
if(i == k) {
y = x; // y = x1, x2, x4, x8, ...
k <<= 1;
}
}
}
void findfac(long long n) {
if(n == 4) {
fc[0] = fc[1] = 2; fcn = 2;
return;
}
if(miller_rabin(n)) {
fc[fcn++] = n;
return;
}
for(;;) { // 不是质数,必定有因数
long long p = pollard_rho(n, rand()%(n-3)+3);
if(p != n) {
findfac(p);
findfac(n/p);
return;
}
}
}
注:以上讲解非常没有逻辑联系,因为我找的文章我都看不懂,而代码实现非常方便,因此直接实现代码就好了。
行列式
用高斯消元求。
inline int det() {
int ret = 1, w = 1;
for(int i = 0; i < n; i++) {
int p = i;
for(int j = i+1; j < n; j++) if(a[j][i] != 0) p = j;
if(i != p) {
w = -w; // 交换两行行列式值取反
for(int j = 0; j < n; j++) swap(a[i][j], a[p][j]);
}
int invii = inv(a[i][i]);
for(int j = n-1; j >= i; j--) for(int k = i+1; k < n; k++) {
a[k][j] -= (long long)a[k][i] * invii % _mod * a[i][j] % _mod;
if(a[k][j] < 0) a[k][j] += _mod;
}
}
for(int i = 0; i < n; i++) ret = (long long)ret * a[i][i] % _mod;
return w == 1 ? ret : _mod-ret;
}
在做矩阵树定理时,有人说行列式要取绝对值,但事实证明不需要取。
二次剩余
4 3 2 1 1 1 5 3 9 4 1 1 5 1 1 3 1 1 5 2 1 1 1 1 7 2 1 3 5 1 4 1 1 1 4 1 1 1 2 2 6 3 2 1 6 3 1 1 7 3 2 2 4 1 1 5 5 1 2 1 1 2 5 1 4 1 1 1 4 1 4 1 6 1 2 3 6 1 1 2 3 1 4 2 1 1 1 1 6 1 4 2 5 1 2 5 4 1 3 2 7 1 1 1 1 1 6 1 12 2 2 2 5 1 1 2 8 1 2 1 1 3 4 2 1 1 8 1 2 5 4 2 1 2 1 2 4 2 3 2 5 1 2 2 1 1 5 1 2 5 4 2 2 4 4 1 2 1 2 2 5 5 7 4 7 1 1 1 3 2 6 2 1 1 1 1 4 1 3 4 5 1 2 1 7 1 1 5 6 2 2 3 4 1 2 2 2 1 4 1 1 2 1 3 4 1 3 1 1 1 5 1 1 1 9 3 10 2 1 2 6 2 1 3 7 4 1 2 6 3 1 2 5 1 1 2 8 1 2 1 1 1 5 1 3 2 1 1 4 1 2 1 2 1 5 1 3 1 1 1 5 1 2 2 1 1 5 1 1 1 9 1 1 1 1 1 1 2 5 4 1 2 4 1 5 1 5 1 2 2 2 1 4 1 2 2 2 1 4 3 3 2 5 3 8 2 1 1 3 1 6 2 1 1 6 1 1 1 1 1 2 1 4 2 3 3 4 1 1 2 1 2 5 2 3 1 6 1 1 1 1 1 1 2 4 2 2 2 6 1 2 2 8 4 1 2 4 1 1 3 1 1 6 2 1 3 5 1 4 2 6 5 1 1 4 2 1 2 8 5 1 1 5 4 2 1 5 2 1 1 2 1 4 1 2 1 1 1 7 1 1 1 2 1 5 1 2 1 2 2 4 1 2 1 2 1 5 2 1 2 1 2 5 2 2 1 6 1 2 3 1 1 5 1 3 1 6 1 2 2 8 5 6 1 1 3 1 2 4 1 2 1 1 3 4 2 1 2 1 1 5 2 3 2 6 2 3 1 7 3 2 1 5 2 1 1 8 1 1 2 1 1 5 1 3 1 1 1 5 2 2 1 1 2 4 2 2 1 9 1 3 1 5 1 1 2 2 1 5 2 1 1 1 1 6 2 1 2 2 1 4 2 2 4 4 2 1 1 1 2 6 2 1 2 7 2 1 3 5 2 1 3 1 1 4 1 1 1 2 1 6 1 5 1 6 3 2 1 5 1 3 2 6 2 1 4 6 4 2 1 4 2 3 1 6 1 3 3 5 1 3 1 1 2 4 1 1 1 2 1 7 2 2 3 5 1 1 4 5 1 3 2 6 1 4 2 5 2 1 3 6 1 1 1 4 1 5 7 4 1 3 4 5 2 1 4 5 1 1 1 1 3 4 1 1 5 5 2 3 1 7 3 3 1 4 1 2 3 1 1 4 1 2 3 6 1 1 1 4 1 5 2 4 1 5 1 1 1 1 1 1 1 4 1 3 1 7 3 1 4 4 1 1 2 1 2 5 1 4 2 5 1 1 2 1 2 5 1 2 2 1 1 5 1 1 4 6 1 3 2 1 1 4 1 3 3 5 2 2 1 8 3 1 2 5 2 1 1 1 3 5 1 1 1 2 2 4 1 2 1 1 3 4 3 4 1 5 1 1 1 1 3 4 1 3 1 1 2 4 3 3 2 4 2 2 1 8 2 1 3 7 1 2 2 6 4 1 2 4 3 1 1 2 1 4 1 1 4 7 2 1 1 2 1 4 1 2 4 5 1 3 1 1 2 5 3 2 1 5 1 5 2 4 1 3 4 4 1 4 1 1 1 5 4 2 1 4 1 2 1 1 3 4 1 3 2 1 1 4 1 1 1 2 1 1 1 4 1 1 6 4 1 2 1 1 1 6 1 5 1 5 1 3 4 4 2 2 1 7 1 1 4 1 1 5 1 1 2 1 2 4 2 2 2 1 1 4 2 1 1 8 1 2 2 7 1 4 3 6 4 6 1 5 2 5 4 8 5 7 1 1 1 1 1 1 1 5 1 3 1 6 4 1 1 6 1 1 3 2 1 5 2 1 1 1 2 4 3 4 1 4 1 1 1 1 2 6 2 1 3 1 1 5 5 6 1 2 3 6 1 1 1 1 3 6 4 1 2 5 1 1 2 1 2 4 1 2 1 2 1 5 2 5 1 4 1 2 1 2 1 5 1 4 1 1 1 4 1 2 2 1 1 5 1 5 1 5 1 1 1 4 1 4 1 2 1 1 1 1 1 5 1 2 3 6 3 1 1 6 1 2 1 2 2 4 2 1 4 6 5 7 4 8 3 2 1 5 2 1 1 1 1 6 1 2 1 8 1 1 1 1 4 5 3 1 1 1 1 6 1 9 4 8 3 2 2 5 1 1 2 1 3 4 1 2 5 6 4 1 1 4 1 2 2 7 1 1 3 7 3 2 2 6 3 3 1 4 1 3 1 1 2 4 2 2 3 6 4 2 1 5 2 1 1 1 2 4 1 1 1 1 4 4 1 3 4 4 2 5 1 4 2 1 1 2 1 7 1 2 1 7 2 2 1 6 2 1 4 5 1 5 1 6 1 1 2 7 1 1 1 2 1 6 1 1 1 1 1 1 1 5 1 2 2 1 2 4 1 1 1 2 1 1 1 4 1 2 3 6 1 5 2 4 1 4 1 6 1 1 3 10 3 1 1 4 1 1 1 2 1 1 1 4 3 1 1 1 2 4 1 2 2 1 1 6 1 1 1 8 1 1 3 2 1 4 1 3 2 7 2 2 1 6 1 1 6 4 2 3 1 7 4 2 1 5 1 1 2 7 2 2 3 5 1 2 1 1 1 6 2 1 1 3 1 6 2 1 3 4 2 2 1 7 1 6 1 6 1 2 1 7 2 4 1 4 1 6 1 5 5 8 1 9 1 1 1 1 4 5 4 2 1 4 1 2 1 3 1 4 2 2 1 7 1 1 2 2 1 5 1 1 1 1 2 6 1 2 1 1 2 6 3 2 2 4 1 1 2 8 2 3 2 5 3 2 3 6 1 1 3 6 2 1 2 1 1 5 3 1 1 6 1 2 2 7 2 3 1 6 1 1 5 5 2 5 1 4 1 2 1 2 2 4 1 1 2 9 3 8 1 1 1 3 2 4 1 3 3 6 2 1 1 1 1 6 2 4 1 4 1 1 2 1 1 1 1 5 1 2 2 6 2 1 1 1 1 1 1 4 1 11 3 2 2 5 1 1 4 1 1 6 5 5 2 4 1 5 2 2 2 1 1 4 2 1 4 5 2 3 3 4 1 2 2 7 1 4 2 5 1 5 2 4 2 11 2 2 2 6 4 1 2 7 1 2 1 7 5 5 1 1 1 2 1 6 1 3 1 1 1 6 6 5 2 3 1 1 1 4 1 11 1 1 3 1 1 7 1 3 1 6 2 1 3 5 1 2 1 1 2 6 5 1 1 5 4 7 1 3 2 6 2 1 2 1 1 5 1 2 1 1 1 1 1 4 1 3 2 6 2 1 1 3 1 4 2 1 2 2 1 5 2 2 3 4 2 1 1 1 2 5 2 1 1 8 1 1 2 1 1 6 2 2 1 2 1 5 2 1 2 6 2 1 1 3 1 4 2 1 1 3 1 4 1 1 2 1 1 7 1 1 1 8 1 1 4 6 1 1 5 5 1 1 2 2 1 6 1 1 2 1 1 5 3 1 1 1 1 6 2 1 1 1 1 6 5 6 1 2 5 4 1 1 2 1 3 4 1 1 6 6 1 1 2 1 1 4 1 1 1 1 1 1 2 4 1 3 1 2 1 4 1 3 1 1 1 6 3 1 1 6 1 2 1 9 1 1 1 9 3 1 1 6 1 1 2 2 1 5 3 2 3 5 6 5 1 1 1 1 1 7 1 1 2 3 1 5 4 1 2 4 1 2 1 8 2 1 1 1 1 6 1 2 1 1 1 9 2 2 1 5 4 2 1 4 1 2 1 9 1 3 3 5 7 4 2 1 1 1 1 7 5 1 1 5 1 2 1 2 1 4 1 4 3 4 1 1 1 3 2 4 1 1 4 1 1 4 1 2 2 2 1 4 2 1 1 1 2 5 1 1 2 1 3 4 2 1 1 1 2 6 1 4 1 5 1 3 3 5 2 1 1 1 2 6 5 7 2 4 1 4 1 2 1 2 1 5 1 11 1 3 1 2 1 5 3 2 1 5 1 1 1 3 1 5 1 3 1 1 1 5 2 3 1 7 2 2 1 6 1 3 1 7 2 2 2 1 1 6 1 2 2 5 1 1 3 1 1 5 1 1 1 1 4 4 1 2 2 2 1 5 7 4 1 2 4 5 2 2 1 2 1 6 1 1 1 1 2 4 2 1 1 8 3 3 2 4 1 2 1 1 1 1 1 6 1 1 2 6 1 1 1 3 2 5 2 1 4 6 1 1 1 1 2 4 1 2 1 2 1 6 2 1 1 7 1 1 1 1 3 5 1 1 3 7 1 4 3 4 1 1 1 3 1 5 3 4 1 4 2 3 1 7 2 1 3 5 3 1 4 4 1 1 2 1 3 4 2 1 2 2 1 6 1 1 4 6 1 1 3 5 1 1 2 1 1 1 1 4 3 2 1 1 1 4 2 3 1 7 3 8 1 3 1 1 2 4 2 1 1 3 1 5 1 2 1 8 1 1 2 7 1 2 1 2 2 4 1 3 3 5 1 2 1 1 1 1 1 4 1 4 2 6 1 1 1 1 1 6 2 2 2 1 1 5 2 1 1 1 2 5 1 2 3 5 2 3 3 5 3 1 3 4 2 2 2 7 4 1 1 9 1 1 2 4 1 5 1 5 3 4 1 4 2 1 4 6 1 1 1 1 1 1 1 4 1 2 1 1 3 4 2 1 2 1 2 4 1 3 1 1 2 4 1 2 1 9 4 1 1 5 2 1 2 9 3 1 1 5 1 1 3 7 1 4 3 5 1 1 1 3 1 5 6 5 1 2 1 2 1 5 1 4 1 7 3 1 3 5 3 8 1 4 1 7 5 1 1 5 1 1 1 1 2 6 2 1 2 1 1 4 1 2 1 8 2 2 1 1 2 4 3 1 1 2 1 5 4 1 2 5 2 2 1 6 1 5 2 4 1 1 2 1 3 4 1 2 3 6 1 3 3 6 1 1 1 2 2 4 2 1 2 2 1 4 3 2 3 4 1 1 1 1 1 9 1 1 2 7 1 1 1 8 1 2 5 4 1 1 2 2 1 5 1 1 3 7 1 3 1 7 1 1 1 1 2 6 1 5 1 5 1 2 2 1 1 6 1 3 2 5 1 2 1 1 3 5 5 1 1 4 1 1 1 1 1 1 1 6 1 1 5 5 2 1 2 6 2 1 1 1 2 5 1 4 2 6 2 1 1 2 1 4 2 1 1 1 1 6 2 1 1 1 2 5 1 2 1 1 1 1 1 4 2 11 3 3 1 5 1 1 3 6 1 3 1 2 1 4 1 1 2 2 1 5 1 1 1 1 2 7 1 1 1 3 1 5 2 1 2 6 1 1 4 1 1 4 1 2 1 1 1 1 1 5 1 1 1 8 1 1 3 1 2 4 1 2 1 3 1 5 7 5 1 1 5 5 2 2 1 6 3 1 2 1 1 4 3 1 3 5 1 3 3 6 2 1 1 2 1 4 1 2 3 6 1 1 1 1 3 5 1 2 1 2 1 6 7 4 1 1 1 3 2 5 3 1 3 4 3 10 3 8 1 2 1 2 2 5 5 1 1 5 1 2 1 8 3 8 4 8 1 4 1 1 1 4 4 2 2 5 1 1 1 2 1 5 2 2 1 1 1 6 2 2 1 1 1 4 1 3 2 1 1 4 1 1 2 3 1 5 4 1 1 5 1 1 1 2 1 7 2 4 1 4 1 2 1 1 3 4 1 2 1 1 2 5 1 1 2 8 1 1 3 1 2 5 3 3 1 5 2 1 1 2 1 4 1 2 5 4 1 2 1 1 1 6 1 4 1 7 6 5 1 2 2 1 2 4 1 1 2 1 1 1 1 5 2 2 1 1 1 5 1 1 3 1 1 4 1 1 1 1 1 2 1 4 1 1 1 1 2 1 1 5 3 1 1 8 2 1 2 5 1 3 2 1 1 5 1 1 2 7 1 2 1 8 1 3 1 1 2 4 1 2 1 2 1 5 1 2 2 1 1 5 1 1 1 2 1 1 1 4 1 1 3 8 1 2 2 6 2 3 3 4 1 2 3 1 1 4 1 1 4 6 1 3 2 1 1 4 1 1 4 1 1 5 7 5 4 1 2 5 2 4 1 5 1 1 4 5 1 2 2 1 2 5 2 1 2 1 1 5 2 1 1 7 2 3 1 6 1 1 1 4 1 5 2 1 1 7 2 1 1 3 1 4 1 4 1 6 1 2 3 6 1 4 1 6 1 1 1 2 1 1 1 5 3 3 1 4 3 1 2 7 2 1 1 1 1 6 2 1 1 1 1 5 1 2 4 5 1 4 1 1 1 4 1 1 6 4 1 1 1 1 2 1 1 4 2 1 2 7 1 1 3 2 1 6 1 1 1 1 2 4 1 1 1 2 3 4 2 1 5 4 1 1 2 3 1 4 1 2 1 3 1 5 4 2 1 5 7 4 1 1 1 2 1 1 1 4 1 1 1 2 2 7 2 1 1 6 1 2 3 1 1 4 2 1 2 1 1 5 3 2 2 6 7 4 3 9 3 1 1 1 2 4 1 1 1 9 1 11 1 2 1 1 1 1 1 4 1 1 1 1 1 1 2 4 1 1 1 2 1 1 1 4 2 1 1 3 1 6 1 10 1 1 2 7 2 3 2 5 2 2 1 1 1 5 1 1 5 6 4 1 2 4 2 4 1 5 3 3 1 5 2 1 2 7 2 2 2 9 1 1 2 5 1 2 3 1 1 5 3 2 2 4 1 2 2 7 2 1 1 2 1 6 4 1 1 5 1 1 1 2 1 1 1 4 1 2 2 1 1 6 3 3 1 4 1 1 2 2 1 6 3 3 1 4 1 1 1 1 1 2 1 5 2 1 3 5 1 4 1 6 1 2 1 1 1 7 2 1 1 1 2 5 3 1 3 4 1 11 1 2 1 1 2 6 1 1 1 1 1 6 1 2 1 3 1 4 1 1 1 1 2 7 5 6 1 3 2 1 1 4 2 1 1 1 2 5 1 2 1 1 2 6 2 2 3 4 3 1 1 2 1 4 1 1 4 1 1 4 1 3 1 1 1 6 2 1 4 4 3 2 2 5 1 1 1 2 2 5 1 2 3 1 1 4 2 1 1 8 1 1 1 4 1 5 1 1 5 4 3 1 4 5 3 1 2 5 2 2 2 7 1 2 1 7 1 2 3 6 1 2 1 2 2 4 1 3 2 1 1 5 2 1 1 9 4 1 1 4 4 2 1 5 1 2 1 1 3 4 2 1 2 1 1 6 2 2 3 5 1 3 1 7 1 1 5 4 1 6 1 4 4 3 1 5 1 2 2 7 2 3 1 5 1 2 2 1 2 5 3 2 2 5 4 9 1 1 1 8 1 1 1 3 1 4 3 1 2 1 1 4 2 2 1 1 2 4 1 3 1 7 2 1 1 2 1 6 2 2 3 4 1 3 3 5 1 1 1 1 2 6 2 1 1 1 1 6 1 1 1 1 3 6 1 2 4 4 3 1 2 7 1 1 3 2