莫比烏斯反演也是反演定理的一種php
既然咱們已經學了二項式反演定理數組
那莫比烏斯反演定理與二項式反演定理同樣,不求甚解,只求會用app
莫比烏斯反演長下面這個樣子(=・ω・=)ide
d|n,表示n可以整除d,也就是d是n的全部因子函數
μ(x)是莫比烏斯函數,它是這樣計算的spa
μ(1) = 1 code
x = p1 * p2 * p3 ……*pk(x由k個不一樣的質數組成)則μ(x) = (-1)^k blog
其餘狀況,μ (x) = 0 ci
好比it
30 = 2 * 3 * 5
μ(30) = (-1)^3
4 = 2 * 2
μ(4) = 0
對於μ(d)函數,它有以下的常見性質:
(1)對任意正整數n有
(2)對任意正整數n有
求μ的函數的方法不少
這裏提供一種線篩的預處理(複雜度O(n)喲~~~)
1 #include<cstdio> 2 const int N = 1e6 + 5; 3 int mu[N], vis[N], prime[N]; 4 int tot;//用來記錄prime的個數 5 void init(){ 6 mu[1] = 1; 7 for(int i = 2; i < N; i ++){ 8 if(!vis[i]){ 9 prime[tot ++] = i; 10 mu[i] = -1; 11 } 12 for(int j = 0; j < tot && i * prime[j] < N; j ++){ 13 vis[i * prime[j]] = 1; 14 if(i % prime[j]) mu[i * prime[j]] = -mu[i]; 15 else{ 16 mu[i * prime[j]] = 0; 17 break; 18 } 19 } 20 } 21 } 22 int main(){ 23 init(); 24 }
上次,有人問我μ爲啥不是miu是mu
這。。。固然均可以啦,μ的英文就是mu,miu是讀音看你習慣
∑(っ °Д °;)っ爲了證實我是對的,我特地百度了希臘字母讀音及科學方面應用
大寫
|
小寫
|
英文讀音
|
國際音標
|
意義
|
Α
|
α
|
alpha
|
/ˈælfə/
|
角度,係數,角加速度
|
Β
|
β
|
beta
|
/'beitə/
|
磁通係數,角度,係數
|
Γ
|
γ
|
gamma
|
/'gæmə/
|
電導係數,角度,比熱容比
|
Δ
|
δ
|
delta
|
/'deltə/
|
變化量,屈光度,一元二次方程中的判別式
|
Ε
|
ε
|
epsilon
|
/ep'silon/
|
對數之基數,介電常數
|
Ζ
|
ζ
|
zeta
|
/'zi:tə/
|
係數,方位角,阻抗,相對粘度
|
Η
|
η
|
eta
|
/'i:tə/
|
遲滯係數,效率
|
Θ
|
θ
|
theta
|
/'θi:tə/
|
溫度,角度
|
Ι
|
ι ℩
|
iota
|
/ai'oute/
|
微小,一點
|
Κ
|
κ
|
kappa
|
/kæpə/
|
介質常數,絕熱指數
|
∧
|
λ
|
lambda
|
/'læmdə/
|
波長,體積,導熱係數
|
Μ
|
μ
|
mu
|
/mju:/
|
磁導係數,微,動摩擦系(因)數,流體動力粘度
|
Ν
|
ν
|
nu
|
/nju:/
|
磁阻係數,流體運動粘度,光子頻率
|
Ξ
|
ξ
|
xi
|
/ksi/
|
隨機數,(小)區間內的一個未知特定值
|
Ο
|
ο
|
omicron
|
/oumaik'rən/
|
高階無窮小函數
|
∏
|
π
|
pi
|
/pai/
|
圓周率,π(n)表示不大於n的質數個數
|
Ρ
|
ρ
|
rho
|
/rou/
|
電阻係數,柱座標和極座標中的極徑,密度
|
∑
|
σ ς
|
sigma
|
/'sigmə/
|
總和,表面密度,跨導,正應力
|
Τ
|
τ
|
tau
|
/tau/
|
時間常數,切應力
|
Υ
|
υ
|
upsilon
|
/ju:p'silən/
|
位移
|
Φ
|
φ
|
phi
|
/fai/
|
磁通,角,透鏡焦度,熱流量
|
Χ
|
χ
|
chi
|
/kai/
|
統計學中有卡方(χ^2)分佈
|
Ψ
|
ψ
|
psi
|
/psai/
|
角速,介質電通量
|
Ω
|
ω
|
omega
|
/'oumigə/
|
歐姆,角速度,交流電的電角度
|
其實莫比烏斯有兩種描述
莫比烏斯第一種描述,通常是這種
莫比烏斯第二種描述,這種也能夠並且有些題這種更好
來作題吧
hdu 1695
http://acm.hdu.edu.cn/showproblem.php?pid=1695
(這題就是容斥那一章的,我就把下面的題意照搬過來了,還記得題目的就跳過題目吧)
題意:給你5個數a,b,c,d,k
在a~b中選一個x, c~d中選一個y,知足gcd(x,y) = k , 求(x,y) 的對數
a, b, c, d, k, 0 < a <= b <= 100,000, 0 < c <= d <= 100,000, 0 <= k <= 100,000
在題目描述的最後一行有一句話,多組裏面全部的a和c都是1(這題目不是坑爹嗎(╯‵□′)╯︵┻━┻那輸入a和c有什麼用)
而後題目變成
在1~b中選一個x, 1~d中選一個y,知足gcd(x,y) = k , 求(x,y) 的對數 。。。(無語中。。。)
前面思路同樣
先把問題就轉化爲求1~a區間 和 1~b區間,gcd(x,y) = 1對數的問題
設f(d)爲知足gcd(x,y)=d的x,y的對數
咱們根據莫比烏斯第二描述來作
那F(1) = f(1) + f(2) + f(3) + ....
F(2) = f(2) + f(4) + f(6) +.....
咱們能夠看出F(d)就是知足gcd(x,y)爲d的倍數的x,y的對數
那F(d)的公式就容易求了
F(d) = (a/d) * (b/d)
(在1~a中,有a/d個數是d的倍數,在1~b中,有b/d個數是d的倍數,這些數無論怎麼選擇,構成的gcd(x,y)都是d的倍數)
由於
F(1) = f(1) + f(2) + f(3) + ....
因此
f(1) = μ(1)*F(1) + μ(2)*F(2) + μ(3)*F(3) + ...
AC代碼:
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 typedef long long LL; 5 const int N = 1e6 + 5; 6 int mu[N], vis[N], prime[N]; 7 int tot;//用來記錄prime的個數 8 void init(){ 9 mu[1] = 1; 10 for(int i = 2; i < N; i ++){ 11 if(!vis[i]){ 12 prime[tot ++] = i; 13 mu[i] = -1; 14 } 15 for(int j = 0; j < tot && i * prime[j] < N; j ++){ 16 vis[i * prime[j]] = 1; 17 if(i % prime[j]) mu[i * prime[j]] = -mu[i]; 18 else{ 19 mu[i * prime[j]] = 0; 20 break; 21 } 22 } 23 } 24 } 25 LL Mobius(int a, int b){ 26 LL ret = 0; 27 for(int i = 1; i <= a; i ++){//由於公式中有a/i,因此for到a就能夠了 28 ret += 1ll * mu[i] * (a / i) * (b / i); 29 } 30 //咱們如今求完了總對數,可是題目要求的相似(5,7)和(7,5)算一種 31 //因此接下來咱們開始去重 32 LL temp = 0; 33 for(int i = 1; i <= a; i ++){ 34 temp += 1ll * mu[i] * (a / i) * (a / i); 35 } 36 return ret - temp / 2; 37 //好比a=5,b=7那麼(4,6)這樣子的區間不可能有重複的(6,4) 38 //因此重複的部分只在1~a中,因此最後減去一半的重複區間就行了 39 } 40 int main(){ 41 init(); 42 int T, a, b, c, d, k; 43 scanf("%d", &T); 44 for(int cas = 1; cas <= T; cas ++){ 45 scanf("%d%d%d%d%d", &a, &b, &c, &d, &k); 46 if(k == 0){ 47 printf("Case %d: 0\n", cas); 48 continue; 49 } 50 b /= k; d /= k; 51 if(b > d) swap(b, d); 52 printf("Case %d: %I64d\n", cas, Mobius(b, d)); 53 } 54 }
/////////////////此處施工中//////////////////
暫時棄坑。。。。
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=94200#overview
峯神掛的莫比烏斯反演章節,有興趣本身去作作,不會的去百度。。。。