Description
神犇YY虐完数论后给傻×kAc出了一题
给定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)为质数的(x, y)有多少对
kAc
这种傻×必然不会了,于是向你来请教
……
多组输入
Input
第一行一个整数T 表述数据组数
接下来T行,每行两个正整数,表示N, M
Output
T
行,每行一个整数表示第i组数据的结果
Sample Input
2
10 10
100 100
10 10
100 100
Sample Output
30
2791
2791
HINT
T = 10000
N, M <= 10000000
同2818...
http://blog.csdn.net/lqybzx/article/details/40516835
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
int mu[10000001],prime[10000001];
int g[10000001];
int sum[10000001];
bool check[10000001];
int tot;
inline void findmu()
{
memset(check,false,sizeof(check));
mu[1]=1;
int i,j;
for(i=2;i<=10000000;i++)
{
if(!check[i])
{
tot++;
prime[tot]=i;
mu[i]=-1;
g[i]=1;
}
for(j=1;j<=tot;j++)
{
if(i*prime[j]>10000000)
break;
check[i*prime[j]]=true;
if(i%prime[j]==0)
{
mu[i*prime[j]]=0;
g[i*prime[j]]=mu[i];
break;
}
else
{
mu[i*prime[j]]=-mu[i];
g[i*prime[j]]=mu[i]-g[i];
}
}
}
for(i=1;i<=10000000;i++)
sum[i]=sum[i-1]+g[i];
}
int main()
{
int T;
scanf("%d",&T);
findmu();
while(T>0)
{
T--;
int n,m;
scanf("%d%d",&n,&m);
if(n>m)
{
int tt=n;
n=m;
m=tt;
}
int d,j=0;
long long ans=0;
for(d=1;d<=n;d=j+1)
{
j=min(n/(n/d),m/(m/d));
ans+=(long long)(sum[j]-sum[d-1])*(n/d)*(m/d);
}
printf("%lld\n",ans);
}
return 0;
}