OI 數論中的上界估計與時間複雜度證明

sun123zxy發表於2023-04-18

預備

0.1 漸進符號

其實不少高等數學 / 數學分析教材在講解無窮小的比較時已經相當嚴謹地介紹過大 O、小 O 記號,然而各種歷史習慣記法的符號濫用(abuse of notation) 直到現在都讓筆者頭疼. These notations seem to be innocent, but can be catastrophic without careful manipulation. For example,

  • n=O(n2)n2=O(n2)n=n2

    Knuth 在《具體數學》裡舉出的例子. “=” 隱含的對稱性使其在 g(x)=O(f(x)) 中格格不入. 事實上,將 O(f(x)) 看作“階不高於 f(x) 的所有函式的集合”是比“某個階不高於 f(x) 的函式”更嚴謹的理解. 因此,本文將使用 f(x)O(g(x)) (有時也記為 O(f(x))O(g(x)))的集合論符號代替傳統的 f(x)=O(g(x)) 記法.

  • n2sinnO(n2)i=1ni2sinii=1nO(i2)O(i=1ni2)O(n3) 或更一般的, g(x)O(f(x))P(n,i)g(i)P(n,i)O(f(i))O(P(n,i)f(i))

    沒看出有啥問題,對吧?筆者在寫作此文時犯了同樣的錯誤. 請注意,大 O 記號的作用物件是函式,f(i) 是什麼?它只是個函式值,是確定的數——這是因為 i 也是求和列舉中確定的數,而不是 n 這種真正代表變元的記號. 所以 O(f(i)) 是什麼?它什麼也不是.

    這種錯誤的出現是在所難免的,我們太習慣用 xx3+5x2+x 這種變元都不明確的記號來表示函式了 . 寫成 f(x) 也不嚴謹,因為只有 f 才應代表函式本身,f(x) 只能是函式值. 這樣我們就可以放心地寫下 O(f),不用擔心把變元與確定值弄混了.

    然而大家還是喜歡寫 O(n2)O(en2),而不是奇怪的 O(id2)O(expid2). 所以,我們大概只能沿用這種不太嚴謹的記號,並時刻提醒自己加倍小心了. (形如 xex2λ 風格“匿名函式”記號可能更好?)

    但上述命題從結論上是正確的. 正確的推導過程應為 P(n,i)g(i)P(n,i)Cf(i)CP(n,i)f(i)O(P(n,i)f(i)) 

    第一步是直接由大 O 記號的定義得到的結果.

Wikipedia 中有一張詳盡的表格介紹了各種漸進符號的定義,OI Wiki 上也有極好的講解,尚不熟練的讀者可以參考. 有興趣仔細研究的讀者可以參考《具體數學》第九章 、Wikipedia 及其 reference(個人推薦 Knuth 關於 OΩΘ 的短文 ). 本文除用 “” 和“”替代 “=” 外,完全使用 Knuth 提議的記號體系.

0.2 調和數 H(n) / 調和級數

調和級數的部分和 H(n) 定義為 H(n)=i=1n1i 透過一些與 e 有關的數列放縮可以證明 limn(H(n)logn)=c,其中 c0.577 是 Euler 常數. 因此 nH(n)nlognΘ(logn).

0.3 自然數等冪和 Pp(n) / p - 級數

p - 級數可視為調和級數的推廣. 其部分和定義為 Pp(n)=i=1nip

p - 級數具有如下性質:

  • p>1 時,p - 級數收斂;

  • p=1 時,p - 級數是調和級數;

  • <p<1 時,我們指出 Pp(n)11pn1pΘ(n1p)

<p<1p - 級數的漸進估計可以從連續冪函式積分的角度理解. 證明這漸進性,離散情況下,可對 np 差分後字首和 + 二項式定理得到高次項係數,或可用離散微積分理論得到精確表示(參見《具體數學》 );連續情況下,Lagrange 中值定理應為較簡單的估計方法. 這裡從略. 總之,我們得到: Pp(n){Θ(n1p)p<1Θ(nlogn)p=1Θ(1)p>1

1 約數函式 σz(n)

約數函式(Divisor Function,也可稱為除數函式、因數函式)是與 n 的因子有關的一類函式,定義如下:

Definition 1 (約數函式) σz(n)=dndz

z=0 時,σ0(n) 被稱為約數個數函式(number-of-divisors function),常被記為 d(n)τ(n). 當 z=1 時,σ1(n) 被稱為約數和函式(sum-of-divisors function),常直接記為 σ(n).

Example 1 估計 σ0(n) 的漸進上界.

也就是估計 n 的因子的數量. 一個廣為人知的上界是 2n,因為 n 的所有小於 n 的因子 d 均與另一因子 nd 一一對應.

事實上進一步可以證明 σ0(n)o(nϵ)ϵ>0 ,雖然這在 OI 中並不實用.

Example 2 估計 σ0^(n)=i=1nσ0(i) 的漸進上界.

即估計 1n 中所有數因子個數的和. 這是一個形式上鮮為人知但其應用廣為人知的例子. 變換求和順序,容易得到

σ0^(n)=i=1nσ0(i)=i=1ndi1=d=1nndd=1nnd=nH(n)O(nlogn)

顯然,這比 O(nn) 的平凡估計好上不少. 本例的思路不僅是埃氏篩(Sieve of Eratosthenes)的理論基礎,也在杜教篩、快速 Mobius 變換、gcd 卷積 等處出現.

進一步利用此技巧和 p - 級數的估計,我們甚至能在仔細研究 σz(n) 前就得到其字首和的漸進估計:

Example 3 估計 σz^(n)=i=1nσz(i) 的漸進上界.

σz^(n)=i=1nσz(i)=i=1ndidz=d=1ndzndnd=1ndz1=nP1z(n){O(nz+1)z>0O(nlogn)z=0O(n)z<0

遺憾的是,對此字首和做差分並不能得到 σz(n) 的優秀估計.

現在引入一個重要放縮技巧,其在後續估計中屢試不爽.

Proposition 1 dnf(d)i=1nf(ni)

顯然,右式比左式多算了 in 的項,因此命題是正確的. 但我們還可以做得更好:

Proposition 2 dnf(d)i=1nf(i)+f(ni)

n 分治. 我們其實已經在 Example 1 估計 σ0(n) 時用過此技巧了.

Example 4 估計 σ1(n) 的漸進上界.

Proposition 1σ1(n)=dndi=1nninH(n)O(nlogn)

可以證明用 Proposition 2 不會得到更優的結果.

我們發現了一個有趣的事實:σ1(n)σ0^(n) 的漸進上界均為 O(nlogn).

Example 5 估計 σz(n) 的漸進上界.

Proposition 2p - 級數的性質:

σz(n)=dndzi=1niz+niz{2i=1nniz2nzi=1niz=2nzPz(n)z02i=1niz=2Pz(n)z<0{2nzO(1)z>12nO(logn)z=12nzO(n1z2)0z<12O(n1+z2)1<z<02O(logn)z=12O(1)z<1={O(nz)z>1O(nlogn)z=1O(n1+z2)1<z<1O(logn)z=1O(1)z<1

我們得到了一個相當優秀的漸進上界. 值得關注的是:

  • z=0 時,σ0(n)O(n12). 這與 Example 1 的結果一致.
  • z=12 時,σ12(n)O(n34),即 dndO(n34). 洛谷 P4980 Polya 定理模板題 的一種比較 trivial 的解法 的時間複雜度證明就來源於此. 我們之後還會在整除分塊與杜教篩中見到它.

另外,如果只使用 Proposition 11<z<1 部分的漸進上界將只能估計至 O(n). 因此 Proposition 2 是更為優越的.

約數函式更復雜的上限與漸進估計可參考 Wikipedia.

2 整除分塊

也被稱為數論分塊. 求 i=1nf(i)g(ni) 我們按 d=ni 分塊求和: dg(d)ni=df(i) 可以證明,對一指定的 d,滿足 d=nii 取遍一連續區間,故若 f 的字首和能 O(1) 求出,塊數量 #{ni}i=1n 即該演算法的時間複雜度. 注意到當 in 時,ni 最多隻有 n 種取值,而 in 時,1nin 表明其也最多隻有 n 種取值. 因此整除分塊的時間複雜度 T1(n)=#{ni}i=1n2nO(n)

方便起見,後文記 D(n)={ni}i=1n.

2.1 整除分塊巢狀

Proposition 2 加強,我們有如下通用放縮:

Proposition 3 dnf(d)dD(n)f(d)i=1nf(i)+f(ni)

LHS 成立的關鍵在於 {d:dn}D(n);而 RHS 的本質就是上述對整除分塊塊數量上界的估計.

注意到 Proposition 2Example 5 證明的核心,而 Proposition 3Proposition 2 的加強版,故仿造 Example 5 的證明,我們有

Example 6 Sz(n)=dD(n)dz 則前述 Example 5σz(n) 的上界與漸進上界也同樣適用於 Sz(n).

現在可以對巢狀整除分塊 i=1nf(i)j=1nig(j)h(nij) 的時間複雜度 T2 做出估計了. 對 Example 6z=12,立刻有 T2(n)=dD(n)T1(d)2dD(n)d=2S12(n)4nP12(n)O(n34)

我們還可以進一步歸納. 假定 m0,zm:0zm<1,Tm(n)=O(nzm),我們有

Tm+1(n)=dD(n)Tm(d)CdD(n)nzm=CSzm(n)O(n1+zm2)

因此 zm+1=1+zm2. 邊界條件 z0=0,數列遞推求得 zm=12m,檢驗滿足條件. 因此 m 重巢狀整除分塊的時間複雜度 Tm(n)O(n12m)

3 杜教篩

杜教篩可以以低於線性的時間複雜度求解某些數論函式的字首和. 其思路並不複雜. 設 f 為一數論函式,我們希望快速求得其字首和 f^(n)=i=1nf(i). 考慮數論函式 gh=gfh(n)=dng(d)f(nd) 兩端做字首和得 h^(n)=i=1nh(i)=i=1ndig(d)f(id)=d=1ng(d)i=1ndf(i)=d=1ng(d)f^(nd)=g(1)f^(n)+d=2ng(d)f^(nd) 因此 f^(n)=1g(1)(h^(n)d=2ng(d)f^(nd))

故若 gh 的字首和可 O(1) 算得,根據上式整除分塊即可遞迴地計算出 f 的字首和.

下面分析演算法的複雜度. 注意到 nij=nij 故單輪遞迴涉及到的自變數均可表示為 d=ni 的形式. 一個 f^(d) 做整除分塊耗時 T1(d),若採用記憶化遞迴,由上節分析,演算法總時間複雜度為 dD(n)T1(d)=T2(n)O(n34)

但我們還可以做得更好——考慮先用 O(K) 的時間複雜度線性篩出前 Kf(n) 並求字首和,則遞迴求解時,dKf^(d) 就無需再向下遞迴了. 為分析此類時間複雜度,對 Proposition 3 做最後一點擴充套件:

Proposition 4 dnd>Kf(d)dD(n)d>Kf(d)K<inf(i)+1imin{nK,n}f(ni)

特別的,當 K>n 時,有

dnd>Kf(d)dD(n)d>Kf(d)1inKf(ni)

故用 Proposition 4 ,當 K>n 時,演算法在遞迴部分的時間複雜度降低為

dD(n)d>KT1(d)=1inKT1(ni)1inKCni=Cn1inKi12=CnP12(nK)nO((nK)12)O(nK12)

總時間複雜度為 O(K)+O(nK12)

為最小化時間複雜度,取 K=n23,得到最優時間複雜度 O(n23).

這部分的時間複雜度證明主要參考了文章.

References

1. Abuse of notation - wikipedia. (n.d.). https://en.wikipedia.org/wiki/Abuse_of_notation#Function_notation.
2. Graham, R. L., Knuth, D. E., & Patashnik, O. (1994). Concrete mathematics: A foundation for computer science (second, pp. 443–449). Addison-Wesley.
3. Big o notation - wikipedia # family of bachmann–landau notations. (n.d.). https://en.wikipedia.org/wiki/Big_O_notation#Family_of_Bachmann%E2%80%93Landau_notations.
4. 複雜度 - OI wiki. (n.d.). https://oi-wiki.org/basic/complexity/#%E6%B8%90%E8%BF%9B%E7%AC%A6%E5%8F%B7%E7%9A%84%E5%AE%9A%E4%B9%89.
5. Knuth, D. E. (1976). Big omicron and big omega and big theta. SIGACT News, 8(2), 18–24. https://doi.org/10.1145/1008328.1008329
6. Graham, R. L., Knuth, D. E., & Patashnik, O. (1994). Concrete mathematics: A foundation for computer science (second, pp. 47–56). Addison-Wesley.
7. Divisor function - wikipedia # growth_rate. (n.d.). https://en.wikipedia.org/wiki/Divisor_function#Growth_rate.
8. sun123zxy. (2020). sun123zxy’s blog - 原創OI題目 GCD卷積 problem and solution. https://blog.sun123zxy.top/posts/20201206-gcdconv/.
9. P4980 【模板】pólya 定理 - 洛谷 | 電腦科學教育新生態. (n.d.). https://www.luogu.com.cn/problem/P4980.
10. sun123zxy. (2020). sun123zxy’s blog - 等價類計數:Burnside引理 & Polya定理. http://blog.sun123zxy.top/posts/20200321-burnside/#s-4.3.
11. Ander. (2022). 杜教篩. https://zhuanlan.zhihu.com/p/521699400.

相關文章