数学基础IV 欧拉函数 Miller Rabin Pollard's rho 欧拉定理 行列式

时间:2021-07-03 11:39:14

找了一些曾经没提到的算法。这应该是数学基础系最后一篇。
曾经的文章:
数学基础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