定理:F(n)和f(n)是定义在非负整数集合上的两个函数,并且满足条件[{
m{F(n)}} = sumlimits_{{
m{d|n}}}^{} {{
m{f}}(d)}
% MathType!MTEF!2!1!+-
% feaagKart1ev2aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLn
% hiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYbItLDharqqtubsr
% 4rNCHbWexLMBbXgBd9gzLbvyNv2CaeHbl7mZLdGeaGqiVu0Je9sqqr
% pepC0xbbL8F4rqqrFfpeea0xe9Lq-Jc9vqaqpepm0xbba9pwe9Q8fs
% 0-yqaqpepae9pg0FirpepeKkFr0xfr-xfr-xb9adbaqaaeGaciGaai
% aabeqaamaabaabauaakeaacaqGgbGaaeikaiaab6gacaqGPaGaeyyp
% a0ZaaabCaeaacaqGMbGaaiikaiaadsgacaGGPaaaleaacaqGKbGaae
% iFaiaab6gaaeaaa0GaeyyeIuoaaaa!4B7C!
],那么我们得到结论[f(n) = sumlimits_{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) = sumlimits_{d|n}^{} {f(d)} Rightarrow f(n) = sumlimits_{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{ egin{array}{l}1,d = 1\{( - 1)^k},d = {p_1}*{p_2}*...{p_k}\0,end{array}
ight.
% MathType!MTEF!2!1!+-
% feaagKart1ev2aaatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLn
% hiov2DGi1BTfMBaeXatLxBI9gBaerbd9wDYLwzYbItLDharqqtubsr
% 4rNCHbWexLMBbXgBd9gzLbvyNv2CaeHbl7mZLdGeaGqiVu0Je9sqqr
% pepC0xbbL8F4rqqrFfpeea0xe9Lq-Jc9vqaqpepm0xbba9pwe9Q8fs
% 0-yqaqpepae9pg0FirpepeKkFr0xfr-xfr-xb9adbaqaaeGaciGaai
% aabeqaamaabaabauaakeaacqaH8oqBcaGGOaGaamizaiaacMcacqGH
% 9aqpdaGabaabaeqabaGaaGymaiaacYcacaWGKbGaeyypa0JaaGymaa
% qaaiaacIcacqGHsislcaaIXaGaaiykamaaCaaaleqabaGaam4Aaaaa
% kiaacYcacaWGKbGaeyypa0JaamiCamaaBaaaleaacaaIXaaabeaaki
% aacQcacaWGWbWaaSbaaSqaaiaaikdaaeqaaOGaaiOkaiaac6cacaGG
% UaGaaiOlaiaadchadaWgaaWcbaGaam4AaaqabaaakeaacaaIWaGaai
% ilaaaacaGL7baaaaa!5AE1!
]
(其中p1-pk为互异素数。)
[egin{gathered}
sumlimits_{d|n} {mu (d)} = left{ egin{gathered}
1{ ext{ }}(n = 1) hfill \
0{ ext{ }}(n > 1) hfill \
end{gathered}
ight. hfill \
sumlimits_{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
",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
",i,res1-res2/2);
}
}