解法:莫比乌斯反演,话说SD去年好像也出了题反演题
贴大神的blog题解
http://blog.codebursts.com/bzoj3994/
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
typedef long long ll;
ll num[50011],mu[50011],ans;
int pri[50011],np[50011];
bool p[50011];
int dt,tj,i,j,n,m;
void prepare()
{
ll tz;
int i,j,lim,tot;
lim=50000;
tot=0;
memset(p,true,sizeof(p));
num[1]=1;
mu[1]=1;
for(i=2;i<=lim;i++){
if(p[i]){
pri[++tot]=i;
num[i]=2;
np[i]=1;
mu[i]=-1;
}
for(j=1;j<=tot;j++){
tz=(ll)pri[j]*i;
if(tz>lim)break;
p[pri[j]*i]=false;
if(i%pri[j]==0){
np[pri[j]*i]=np[i]+1;
num[pri[j]*i]=num[i]/(np[i]+1)*(np[i]+2);
mu[pri[j]*i]=0;
break;
}
np[pri[j]*i]=1;
num[pri[j]*i]=num[i]*2;
mu[pri[j]*i]=-mu[i];
}
}
for(i=1;i<=lim;i++){
num[i]+=num[i-1];
mu[i]+=mu[i-1];
}
}
int main()
{
scanf("%d",&dt);
prepare();
for(tj=1;tj<=dt;tj++){
scanf("%d%d",&n,&m);
if(n>m)swap(n,m);
ans=0;
for(i=1,j;i<=n;i=j+1){
j=min(n/(n/i),m/(m/i));
ans+=1ll*num[n/i]*num[m/i]*(mu[j]-mu[i-1]);
}
printf("%lld\n",ans);
}
}
来源:https://www.cnblogs.com/applejxt/p/4445627.html