莫比乌斯反演
定理:F(n)和f(n)是定义在非负整数集合上的两个函数,并且满足条件\[{\rm{F(n)}} = \sum\limits_{{\rm{d|n}}}^{} {{\rm{f}}(d)}
% MathType!MTEF!2!1!+-
% feaagKart1ev2aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLn
% hiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYbItLDharqqtubsr
% 4rNCHbWexLMBbXgBd9gzLbvyNv2CaeHbl7mZLdGeaGqiVu0Je9sqqr
% pepC0xbbL8F4rqqrFfpeea0xe9Lq-Jc9vqaqpepm0xbba9pwe9Q8fs
% 0-yqaqpepae9pg0FirpepeKkFr0xfr-xfr-xb9adbaqaaeGaciGaai
% aabeqaamaabaabauaakeaacaqGgbGaaeikaiaab6gacaqGPaGaeyyp
% a0ZaaabCaeaacaqGMbGaaiikaiaadsgacaGGPaaaleaacaqGKbGaae
% iFaiaab6gaaeaaa0GaeyyeIuoaaaa!4B7C!
\],那么我们得到结论\[f(n) = \sum\limits_{d|n}^{} {\mu (d)F(\frac{n}{d})}
% MathType!MTEF!2!1!+-
% feaagKart1ev2aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLn
% hiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYbItLDharqqtubsr
% 4rNCHbWexLMBbXgBd9gzLbvyNv2CaeHbl7mZLdGeaGqiVu0Je9sqqr
% pepC0xbbL8F4rqqrFfpeea0xe9Lq-Jc9vqaqpepm0xbba9pwe9Q8fs
% 0-yqaqpepae9pg0FirpepeKkFr0xfr-xfr-xb9adbaqaaeGaciGaai
% aabeqaamaabaabauaakeaacaWGMbGaaiikaiaad6gacaGGPaGaeyyp
% a0ZaaabCaeaacqaH8oqBcaGGOaGaamizaiaacMcacaWGgbGaaiikam
% aalaaabaGaamOBaaqaaiaadsgaaaGaaiykaaWcbaGaamizaiaacYha
% caWGUbaabaaaniabggHiLdaaaa!5084!
\]
根据F(n)的定义我们可以得出:
- F(1)=f(1)
- F(2)=f(1)+f(2)
- F(3)=f(1)+f(3)
- F(4)=f(1)+f(2)+f(4)
- F(5)=f(1)+f(5)
- F(6)=f(1)+f(2)+f(3)+f(6)
- F(7)=f(1)+f(7)
- F(8)=f(1)+f(2)+f(4)+f(8)
于是可以推导出f(n):
- f(1)=F(1)
- f(2)=F(2)-F(1)
- f(3)=F(3)-F(1)
- f(4)=F(4)-F(2)
- f(5)=F(5)-F(1)
- f(6)=F(6)-F(3)-F(2)+F(1)
- f(7)=F(7)-F(1)
- f(8)=F(8)-F(4)
可以得到公式:\[F(n) = \sum\limits_{d|n}^{} {f(d)} \Rightarrow f(n) = \sum\limits_{d|n}^{} {\mu (d)F(\frac{n}{d})}
% MathType!MTEF!2!1!+-
% feaagKart1ev2aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLn
% hiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYbItLDharqqtubsr
% 4rNCHbWexLMBbXgBd9gzLbvyNv2CaeHbl7mZLdGeaGqiVu0Je9sqqr
% pepC0xbbL8F4rqqrFfpeea0xe9Lq-Jc9vqaqpepm0xbba9pwe9Q8fs
% 0-yqaqpepae9pg0FirpepeKkFr0xfr-xfr-xb9adbaqaaeGaciGaai
% aabeqaamaabaabauaakeaacaWGgbGaaiikaiaad6gacaGGPaGaeyyp
% a0ZaaabCaeaacaWGMbGaaiikaiaadsgacaGGPaaaleaacaWGKbGaai
% iFaiaad6gaaeaaa0GaeyyeIuoakiabgkDiElaadAgacaGGOaGaamOB
% aiaacMcacqGH9aqpdaaeWbqaaiabeY7aTjaacIcacaWGKbGaaiykai
% aadAeacaGGOaWaaSaaaeaacaWGUbaabaGaamizaaaacaGGPaaaleaa
% caWGKbGaaiiFaiaad6gaaeaaa0GaeyyeIuoaaaa!5F53!
\]
其中μ(d)为莫比乌斯函数
μ(d)的性质:\[\mu (d) = \left\{ \begin{array}{l}1,d = 1\\{( - 1)^k},d = {p_1}*{p_2}*...{p_k}\\0,\end{array} \right.
% MathType!MTEF!2!1!+-
% feaagKart1ev2aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLn
% hiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYbItLDharqqtubsr
% 4rNCHbWexLMBbXgBd9gzLbvyNv2CaeHbl7mZLdGeaGqiVu0Je9sqqr
% pepC0xbbL8F4rqqrFfpeea0xe9Lq-Jc9vqaqpepm0xbba9pwe9Q8fs
% 0-yqaqpepae9pg0FirpepeKkFr0xfr-xfr-xb9adbaqaaeGaciGaai
% aabeqaamaabaabauaakeaacqaH8oqBcaGGOaGaamizaiaacMcacqGH
% 9aqpdaGabaabaeqabaGaaGymaiaacYcacaWGKbGaeyypa0JaaGymaa
% qaaiaacIcacqGHsislcaaIXaGaaiykamaaCaaaleqabaGaam4Aaaaa
% kiaacYcacaWGKbGaeyypa0JaamiCamaaBaaaleaacaaIXaaabeaaki
% aacQcacaWGWbWaaSbaaSqaaiaaikdaaeqaaOGaaiOkaiaac6cacaGG
% UaGaaiOlaiaadchadaWgaaWcbaGaam4AaaqabaaakeaacaaIWaGaai
% ilaaaacaGL7baaaaa!5AE1!
\]
(其中p1-pk为互异素数。)
\[\begin{gathered}
\sum\limits_{d|n} {\mu (d)} = \left\{ \begin{gathered}
1{\text{ }}(n = 1) \hfill \\
0{\text{ }}(n > 1) \hfill \\
\end{gathered} \right. \hfill \\
\sum\limits_{d|n} {\frac{{\mu (d)}}{d}} = \frac{{\varphi (n)}}{n} \hfill \\
\end{gathered} \]
用线性筛求莫比乌斯函数值:
const int maxn=1e5+7; bool vis[maxn]; int prime[maxn],mu[maxn]; int cnt; void Init(int N)///线性筛求莫比乌斯函数的值 { //int N=maxn; memset(vis,0,sizeof(vis)); mu[1] = 1; cnt = 0; for(int i=2; i<N; i++) { if(!vis[i]) { prime[cnt++] = i; mu[i] = -1; } for(int j=0; j<cnt&&i*prime[j]<N; j++) { vis[i*prime[j]] = 1; if(i%prime[j]) mu[i*prime[j]] = -mu[i]; else { mu[i*prime[j]] = 0; break; } } } }
例题:hdu-1695
代码:
#include <iostream> #include <algorithm> #include <cstring> using namespace std; typedef long long ll; const int mod=10001; int gcd(int a,int b){return (b==0)?a:gcd(b,a%b);}
const int maxn=1e5+7; bool vis[maxn]; int prime[maxn],mu[maxn]; int cnt; void Init(int N)///线性筛求莫比乌斯函数的值 { memset(vis,0,sizeof(vis)); mu[1] = 1; cnt = 0; for(int i=2; i<N; i++) { if(!vis[i]) { prime[cnt++] = i; mu[i] = -1; } for(int j=0; j<cnt&&i*prime[j]<N; j++) { vis[i*prime[j]] = 1; if(i%prime[j]) mu[i*prime[j]] = -mu[i]; else { mu[i*prime[j]] = 0; break; } } } } int main() { int t; cin>>t;//int T=t; Init(100000); for(int i=1;i<=t;i++){ ll res1=0,res2=0; ll a,b,c,d,k; cin>>a>>b>>c>>d>>k; if(b>d)swap(b,d); if(k==0){ printf("Case %d: 0\n",i);continue; } b=b/k;d=d/k; for(int j=1;j<=b;j++){ res1+=mu[j]*(b/j)*(d/j); } for(int j=1;j<=b;j++){ res2+=mu[j]*(b/j)*(b/j); } printf("Case %d: %lld\n",i,res1-res2/2); } }