P3455 [POI2007]ZAP-Queries(莫比乌斯反演)
Posted dreagonm
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3455 [POI2007]ZAP-Queries(莫比乌斯反演)相关的知识,希望对你有一定的参考价值。
思路
和YY的GCD类似但是更加简单了
类似的推一波公式即可
[
F(n)=sum_{n|d}f(d)
]
[ f(n)=sum_{n|d}mu(frac{d}{n})F(d) ]
[ F(d)=lfloorfrac{n}{d} floor imeslfloorfrac{m}{d} floor ]
[ f(x)=sum_{x|d}mu(frac{d}{x}) imeslfloorfrac{n}{d} floor imeslfloorfrac{m}{d} floor ]
[
f(x)=sum_{t=1}^{lfloorfrac{n}{x}
floor}mu(t) imeslfloorfrac{n}{x imes t}
floor imeslfloorfrac{m}{x imes t}
floor
]
然后整除分块即可
代码
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int T,n,m,mu[51000],iprime[51000],isprime[51000],summu[51000],cnt,k;
void prime(int n){
isprime[1]=true;
mu[1]=1;
for(int i=2;i<=n;i++){
if(!isprime[i])
iprime[++cnt]=i,mu[i]=-1;
for(int j=1;j<=cnt&&iprime[j]*i<=n;j++){
isprime[iprime[j]*i]=true;
mu[iprime[j]*i]=-mu[i];
if(i%iprime[j]==0){
mu[iprime[j]*i]=0;
break;
}
}
}
for(int i=1;i<=n;i++)
summu[i]=summu[i-1]+mu[i];
}
long long f(int k){
long long ans=0;
for(int l=1,r;l<=min(n,m);l=r+1){
r=min((n/(n/(l))),(m/(m/(l))));
ans+=1LL*(summu[r]-summu[l-1])*(n/(l*k))*(m/(l*k));
}
return ans;
}
int main(){
prime(50100);
scanf("%d",&T);
while(T--){
scanf("%d %d %d",&n,&m,&k);
if(n<m)
swap(n,m);
printf("%lld
",f(k));
}
return 0;
}
以上是关于P3455 [POI2007]ZAP-Queries(莫比乌斯反演)的主要内容,如果未能解决你的问题,请参考以下文章
luogu P3455 [POI2007]ZAP-Queries