P3327 莫比乌斯反演+整除分块
莫比乌斯反演 + 整除分块
分析
首先,我们给出一个结论:
证明:
设
对于质数
而对于右式,
因此,由乘法原理,所求证式成立。
为了防止混淆,我们将题面中的
n, m 记为N, M
由上述结论,题目的式子转化为:
莫比乌斯反演:若
F(n) = \sum_{n|d}f(d) ,则有f(n) = \sum_{n|d} \mu(\frac{d}{n})F(d)
于是我们设
下面对
设
记
由莫比乌斯反演,
下面对
由整除分块知,
细节见代码:
#include<bits/stdc++.h>
using namespace std;
const int S=50050;
int primes[S], cnt;
bool vis[S];
int mu[S], sum[S];
int h[S];
int g(int b, int l){
return b/(b/l);
}
void init(){
// init sum[]
mu[1]=1;
for(int i=2; i<S; i++){
if(!vis[i]) primes[cnt++]=i, mu[i]=-1;
for(int j=0; i*primes[j]<S; j++){
vis[i*primes[j]]=true;
if(i%primes[j]==0) break;
mu[i*primes[j]]=-mu[i];
}
}
for(int i=1; i<S; i++) sum[i]=sum[i-1]+mu[i];
// init h[]
for(int x=1; x<S; x++){
int &v=h[x];
for(int l=1, r; l<=x; l=r+1){
r=min(x, g(x, l));
v+=x/l*(r-l+1);
}
}
}
int solve(int N, int M){
int res=0;
int n=min(N, M);
for(int l=1, r; l<=n; l=r+1){
r=min(n, min(g(N, l), g(M, l)));
res+=(sum[r]-sum[l-1])*h[N/l]*h[M/l];
}
return res;
}
int main(){
int T; cin>>T;
init();
while(T--){
int N, M; cin>>N>>M;
cout<<solve(N, M)<<endl;
}
return 0;
}