1. 程式人生 > >莫比烏斯反演 HDU1695 GCD

莫比烏斯反演 HDU1695 GCD

莫比烏斯函式

在這裡插入圖片描述
【通俗理解】
我們手裡有兩個函式,不妨F(x)和f(x),且F(x)是易知的,滿足上述(1)(2)中任意一個,則我們可以通過莫比烏斯反演得出f(n)的函式值。

【例題 HDU 1695 GCD】
題意:
給出5個整數a,b,c,d,k,題目保證a=c=1; 對於x;x∈[a,b],y∈[c,d],求gcd(x,y)=k的個數。本題中x y互換視為同一個!
分析:
不妨設F(x)=( gcd(x,y)=k的倍數的數量 ),設f(x)=( gcd(x,y)=k的數量 ),顯然存在倍數關係,滿足(2)。
通過反演即可得出 f(k)=dkμ(dk)F(d) f(k)=\sum_{d|k} μ(\frac{d}{k}) F(d)

由gcd(x,y)=1可得gcd(xk,yk)=k,因此上述a,b,c,d均除以k之後,就相當於求f(1)了。 F(x)是已知的:F(x)=(bx)(dx) F(x) = (\frac{b}{x})*(\frac{d}{x})
所以f(1)可以線上性時間內求出來。
【程式碼】:https://paste.ubuntu.com/p/MGJvFJXxgm/
優化解法:
列舉F(i)的i時,發現一段連續的i,其實F(i)是相等的,所以這一個塊可以一次性計算出來。有這個優化後,HDUOJ耗時0MS.
【程式碼-優化】:https://paste.ubuntu.com/p/22bNdnwqN8/

還有一種解法,打一張矩形表,根據規律篩選,看程式碼好理解,不過時間複雜度O(n*logn),比莫比烏斯反演的線性複雜度慢一些。
【程式碼-普通】:https://paste.ubuntu.com/p/8nvcRh9Qz6/