https://blog.sengxian.com/algorithms/mobius-inversion-formula
公式:
约数形式
F(n)=∑d|nf(d)⟺f(n)=∑d|nμ(d)F(nd)=∑d|nμ(nd)F(d)
F
(
n
)
=
∑
d
|
n
f
(
d
)
⟺
f
(
n
)
=
∑
d
|
n
μ
(
d
)
F
(
n
d
)
=
∑
d
|
n
μ
(
n
d
)
F
(
d
)
F(n)=∑d=1⌊ni⌋f(i⋅d)⟺f(n)=∑d=1⌊ni⌋μ(d)F(i⋅d)
F
(
n
)
=
∑
d
=
1
⌊
n
i
⌋
f
(
i
⋅
d
)
⟺
f
(
n
)
=
∑
d
=
1
⌊
n
i
⌋
μ
(
d
)
F
(
i
⋅
d
)
倍数形式
F(n)=∑n|df(d)⟺f(n)=∑n|dμ(dn)F(d)
F
(
n
)
=
∑
n
|
d
f
(
d
)
⟺
f
(
n
)
=
∑
n
|
d
μ
(
d
n
)
F
(
d
)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn=100010;
LL T,b,d,k,ans1,ans2;
int prime[maxn],Pcnt,mu[maxn],sum[maxn];
bool del[maxn];
void mobius(){
sum[1]=mu[1]=1;
for(int i=2;i<maxn;i++){
if(!del[i]) prime[++Pcnt]=i,mu[i]=-1;
for(int j=1,p;j<=Pcnt&&(p=i*prime[j])<maxn;j++){
del[p]=1;
if(i%prime[j]==0){mu[p]=0; break;}
mu[p]=-mu[i];
}
sum[i]=sum[i-1]+mu[i];
}
}
inline LL solve(LL n,LL m,LL D){
LL ret=0;
for(int i=1,nxt;i<=n;i=nxt+1){
nxt=min(n/(n/i),m/(m/i));
ret+=(sum[nxt]-sum[i-1])*(n/i)*(m/i);
}
return ret;
}
int main(){
scanf("%lld",&T);
mobius();
for(int Case=1;Case<=T;Case++){
ans1=ans2=0;
scanf("%lld%lld%lld%lld%lld",&b,&b,&d,&d,&k);
if(b>d) swap(b,d);
if(k==0) {printf("Case %d: 0\n",Case); continue;}
b/=k,d/=k;
printf("Case %d: %lld\n",Case,solve(b,d,k)-solve(b,b,k)/2);
}
return 0;
}