关于求解某数所有因子欧拉函数的复杂性分析

【命题】

对于给定数 \(n\) ,求解其所有因子的欧拉函数值

本文不讨论朴素做法,仅讨论两种较为常用的求解方法


【法一】

根据公式 \(\displaystyle \boldsymbol \varphi(n)=n\prod_{i=1}^m (1-{1\over p_i})\),其中 \(\displaystyle n=\prod_{i=1}^m p_i\)

对于 \(n\) 的每个因子 \(d\) ,暴力查询 \(\sqrt d\) 范围内的质因子,并筛除

最后核验 \(d\) 是否存在大于 \(\sqrt d\) 的质因子,若存在,则再计算该质因子贡献

复杂度为 \(O(\sqrt d)\)

int phid=d;
for(int i=2;i*i<=d;++i) if(d%i==0) {
    while(d%i==0) d/=i;
    phid=phid/i*(i-1);
}
if(d>1){
    phid=phid/d*(d-1);
}

复杂度计算时,考虑 \(n\) 不大于 \(\sqrt n\) 的因子最多 \(\sqrt n\) 个,故不小于 \(\sqrt n\) 的因子与之成对出现,也不超过 \(\sqrt n\)

故每当出现 \(n\) 一个不大于 \(\sqrt n\) 的因子 \(d\) 时,我们对称考虑与它成对出现的因子 \({n\over d}\)

\(\displaystyle \quad T(n)\)

\(\displaystyle \leq\sum_{d=1}^{\sqrt n}(\sqrt d+\sqrt {n\over d})\)

\(\displaystyle =O(\int_1^{\sqrt n}\sqrt x\text dx)+\sqrt n\cdot O(\int_1^{\sqrt n}{1\over \sqrt x}\text dx)\)

\(\displaystyle =O(x^{3\over 2}|_1^{\sqrt n})+\sqrt n\cdot O(x^{1\over 2}|_1^{\sqrt n})\)

\(\displaystyle =O(n^{3\over 4})+O(n^{3\over 4})\)

\(\displaystyle =O(n^{3\over 4})\)


【法一优化】

由于复杂度计算时,不难发现,小于 \(\sqrt n\) 部分的因子和大于 \(\sqrt n\) 部分的因子复杂度贡献均为 \(O(n^{3\over 4})\)

根据质数定理的推论,\(n\) 范围内质数个数大约为 \({n\over \ln n}\)

故计算 \(n\) 的欧拉函数,仅需枚举 \(\sqrt n\) 范围内的质数,复杂度为 \(O({\sqrt n\over \ln\sqrt n})=O({\sqrt n\over \log n})\)

总求解复杂度如下:

\(\displaystyle \quad T(n)\)

\(\displaystyle \leq \sum_{d=1}^{\sqrt n}({\sqrt d\over \ln \sqrt d}+{\sqrt{n\over d}\over \ln \sqrt{n\over d}})\)

\(\displaystyle =O(\int_1^{\sqrt n}{2\sqrt x\over \ln x}\text dx)+O(\int_1^{\sqrt n}{2\sqrt {n\over x}\over \ln {n\over x}}\text d{n\over x})\)

\(\displaystyle =2\cdot O({1\over 3}\cdot \int_1^{\sqrt n} {\text dx^{3\over 2}\over \ln x^{3\over 2}})\)

\(\displaystyle =O(Li(({\sqrt n})^{3\over 2}))\)

\(\displaystyle =O(Li(n^{3\over 4}))\)

由于 \(\displaystyle \lim_{n\to +\infty} {Li(n)\over ({n\over \ln n})}=1\)

\(\displaystyle T(n)=O({n^{3\over 4}\over \ln n^{3\over 4}})=O({n^{3\over 4}\over \log n})\)

若额外考虑打出 \(m\) 范围内的欧拉函数值,显然 \(m\leq \sqrt n\) 时,对渐进复杂度无影响

\(m>\sqrt n\) 时,第二部分求解 \({n\over d}\) 时,上界修改为 \({n\over m}\)

故求解复杂度优化为 \(\displaystyle O(m+{({n\over m})^{3\over 2}\over \log {n\over m}})\),其中 \(O(m)\) 为欧拉筛复杂度

由于欧拉筛往往被视为预处理,当计算上述结果 \(k\) 次时,每次的均摊复杂度为 \(\displaystyle O({m\over k}+{({n\over m})^{3\over 2}\over \log {n\over m}})\)

由均值不等式,当且仅当 \(\displaystyle {m\over k}={({n\over m})^{3\over 2}\over \log {n\over m}}\) ,即约为 \(m=k^{2\over 5}\cdot n^{3\over 5}\) 时取最小

此时均摊复杂度约为 \(\displaystyle O({m\over k})=O(({n\over k})^{3\over 5})\) 达到最小

总复杂度约为 \(\displaystyle k\cdot O({m\over k})=O(k^{2\over 5}\cdot n^{3\over 5})\)

\(k=1\) 时取 \(m=n^{3\over 5}, T(n)\approx O(n^{3\over 5})\)


【法二】

考虑 \(n\) 的不同质因子数目,最坏情况下为 \(o(\log n)\)

\(n\geq 2\cdot 3\cdot 5\cdot 7\cdots p_m>2\cdot 2\cdot 2\cdot 2\cdots 2=2^m\to m<\log n\)

但均摊意义下,\(n\) 的不同质因子数目为 \(\displaystyle {1\over n}\sum_{i=1}^\infty \lfloor{n\over p_i}\rfloor\)

由埃氏筛的复杂性可得,均摊意义下,不同质因子数目为 \(O(\log \log n)\)

由于枚举 \(n\) 的所有因子时,其不同质因子均为 \(n\) 的不同质因子

故考虑先打出 \(n\) 的所有不同质因子,方法如上,复杂度为 \(O(\sqrt n)\)\(O({\sqrt n\over \log n})\)

后续枚举 \(n\) 的因子时,同样成对枚举,并只使用该 \(o(\log n)\) 数量级的不同质因子去通过公式 \(\displaystyle \boldsymbol \varphi(n)=n\prod_{i=1}^m (1-{1\over p_i})\) 计算欧拉函数值

该部分复杂度为 \(O(\sqrt n)\cdot o(\log n)=o(\sqrt n\log n)\)

总复杂度为 \(O(\sqrt n)+o(\sqrt n\log n)=o(\sqrt n\log n)\)\(O({\sqrt n\over \log n})+o(\sqrt n\log n)=o(\sqrt n\log n)\)

同理,均摊意义下为 \(O(\sqrt n\log\log n)\)

vector<int> divi;
inline void divit(int n){
    divi.clear();
    for(int i=2, I=sqrt(n)+1e-6;i<=I;++i) if(n%i==0) {
        while(n%i==0) n/=i;
        divi.push_back(i);
    }
    if(n>1)
        divi.push_back(n);
}
inline int phi(int n){
    int res=n;
    for(auto p : divi)
        if(n%p==0)
            res=res/p*(p-1);
    return res;
}

【总结】

关于法二与法一的复杂度比较,这里给出计算:

  1. 对于未优化的法一,若法二更优,则 \(\sqrt n\log n\leq n^{3\over 4}\),得出 \(\log n\leq n^{1\over 4}\)

由牛顿迭代计算得 \(n\geq 5503.6646890767315\) 。故在复杂度允许范围内,法二是普遍更优的

  1. 对于预处理质数的法一,若法二更优,则 \(\sqrt n\log n\leq {n^{3\over 4}\over \log n}\),得出 \(\log n\leq n^{1\over 8}\)

由牛顿迭代计算得 \(n\geq 214910065295.76816\approx 2^{31}\) 。故在 int 范围内,预处理质数的法一更优;int 边界时,两者复杂度相差较小;int 范围以外,法二更优

  1. 对于预处理欧拉函数的法一,考虑 \(k\) 远小于 \(n\) 时,若法二更优,则 \(\sqrt n\log n\leq n^{3\over 5}\),得出 \(\log n\leq n^{1\over 10}\)

由牛顿迭代计算得 \(n\geq 3430631121407792.0\approx 3.4\times 10^{15}\) 。故在复杂度允许的范围内,预处理欧拉函数的法一是普遍更优的

  1. 对于均摊意义下的法二与预处理欧拉函数的法一,考虑 \(k\) 远小于 \(n\) 时,若法二更优,则 \(\sqrt n\log\log n \leq n^{3\over 5}\),得出 \(\log \log n\leq n^{1\over 10}\)

这个等式是恒成立的。故在均摊意义下,法二快于法一。


【附录】

给出 \(n\) 以内不同质因子个数 \(m\) 的范围:

|\(n\)|\(10^1\)|\(10^2\)|\(10^3\)|\(10^4\)|\(10^5\)|\(10^6\)|\(10^7\)|\(10^8\)|\(10^9\)|\(10^{10}\)|\(10^{11}\)|\(10^{12}\)|\(10^{13}\)|\(10^{14}\)|\(10^{15}\)|\(10^{16}\)|\(10^{17}\)|\(10^{18}\)|\(10^{19}\)|
|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|
|\(m\)|\(2\)|\(3\)|\(4\)|\(5\)|\(6\)|\(7\)|\(8\)|\(8\)|\(9\)|\(10\)|\(10\)|\(11\)|\(12\)|\(12\)|\(13\)|\(13\)|\(14\)|\(15\)|\(15\)|

可以发现,在复杂度允许范围内,答案与 \(\lg n\) 较为接近

posted @ 2021-07-25 21:28  JustinRochester  阅读(246)  评论(0编辑  收藏  举报