(暫時棄坑)(半成品)ACM數論之旅18---反演定理 第二回 Mobius反演(莫比烏斯反演)((づ ̄3 ̄)づ天才第一步,雀。。。。)

 

莫比烏斯反演也是反演定理的一種php

 

 

 

既然咱們已經學了二項式反演定理數組

 

那莫比烏斯反演定理與二項式反演定理同樣,不求甚解,只求會用app

 

莫比烏斯反演長下面這個樣子(=・ω・=)ide

 

莫比烏斯反演1

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

    (2)對任意正整數n有 

 

 莫比烏斯反演3

 

 

 

 

求μ的函數的方法不少

這裏提供一種線篩的預處理(複雜度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
/ˈ&aelig;lfə/
角度,係數,角加速度
Β
β
beta
/'beitə/
磁通係數,角度,係數
Γ
γ
gamma
/'g&aelig;mə/
電導係數,角度,比熱容比
Δ
δ
delta
/'deltə/
變化量,屈光度,一元二次方程中的判別式
Ε
ε
epsilon
/ep'silon/
對數之基數,介電常數
Ζ
ζ
zeta
/'zi:tə/
係數,方位角,阻抗,相對粘度
Η
η
eta
/'i:tə/
遲滯係數,效率
Θ
θ
theta
/'θi:tə/
溫度,角度
Ι
ι ℩
iota
/ai'oute/
微小,一點
Κ
κ
kappa
/k&aelig;pə/
介質常數,絕熱指數
λ
lambda
/'l&aelig;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 }
View Code

 

 

 

 

 

 

/////////////////此處施工中//////////////////

暫時棄坑。。。。

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=94200#overview

峯神掛的莫比烏斯反演章節,有興趣本身去作作,不會的去百度。。。。

相關文章
相關標籤/搜索