传送门
一道没有真正意义上进行反演的“反演” 题。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int MAXN=1e7+2;
bool vis[MAXN];
int prime[MAXN/10],mu[MAXN],num=0,n,m;
ll f[MAXN];
inline int read() {
int x=0;char c=getchar();
while (c<'0'||c>'9') c=getchar();
while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
return x;
}
inline void linear_shaker() {
mu[1]=1,f[1]=0;
memset(vis,false,sizeof(vis));
for (register int i=2;i<MAXN;++i) {
if (!vis[i]) prime[++num]=i,mu[i]=-1;
for (int j=1;j<=num&&i*prime[j]<MAXN;++j) {
vis[i*prime[j]]=true;
if (i%prime[j]==0) {mu[i*prime[j]]=0;break;}
mu[i*prime[j]]=-mu[i];
}
}
for (int i=1;i<=num;++i)
for (int j=1;j<=MAXN&&j*prime[i]<MAXN;++j)
f[j*prime[i]]+=mu[j];
for (register int i=2;i<MAXN;++i) f[i]+=f[i-1];
}
inline ll cal(int n,int m) {
ll ans=0;
int t=min(n,m),last;
for (int i=1;i<=t;i=last+1) {
last=min(n/(n/i),m/(m/i));
ans+=(f[last]-f[i-1])*(n/i)*(m/i);
}
return ans;
}
int main() {
// freopen("bzoj 2820.in","r",stdin);
int kase=read();
linear_shaker();
while (kase--) {
n=read(),m=read();
printf("%lld\n",cal(n,m));
}
return 0;
}