题目描述
神犇YY虐完数论后给傻×kAc出了一题
给定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)为质数的(x, y)有多少对
kAc这种傻×必然不会了,于是向你来请教……
多组输入
输入输出格式
输入格式:
第一行一个整数T 表述数据组数
接下来T行,每行两个正整数,表示N, M
输出格式:
T行,每行一个整数表示第i组数据的结果
输入输出样例
输入样例#1: 复制
2 10 10 100 100
输出样例#1: 复制
30 2791
说明
T = 10000
N, M <= 10000000
转载
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn =1e7+1;
#define rep(i,a,b) for(int i=a;i<b;i++)
/*
inline void read(int &x)
{
x=0;
static int p;p=1;
static char c;c=getchar();
while(!isdigit(c)){if(c=='-')p=-1;c=getchar();}
while(isdigit(c)) {x=(x<<1)+(x<<3)+(c-48);c=getchar();}
x*=p;
}
*/
//直接读取文件,高级版,但是不能直接输入,只能文件来搞
namespace fastIO {
#define BUF_SIZE 100000
//fread -> read
bool IOerror = 0;
inline char nc() {
//FILE* fp=fopen("123.txt","r");
static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
if(p1 == pend) {
p1 = buf;
pend = buf + fread(buf, 1, BUF_SIZE, stdin);//从显示器读入的话,改为stdin,文件的话,改为相应的文件指针fp
if(pend == p1) {
IOerror = 1;
return -1;
}
}
return *p1++;
}
inline bool blank(char ch) {
return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
}
inline void read(int &x) {
char ch;
while(blank(ch = nc()));
if(IOerror) return;
for(x = ch - '0'; (ch = nc()) >= '0' && ch <= '9'; x = x * 10 + ch - '0');
}
inline void print(long long x)//ong long 类型的输出
{
static int cnt;
static int a[20];
cnt=0;
do
{
a[++cnt]=x%10;
x/=10;
}while(x);
for(int i=cnt;i>=1;i--)putchar(a[i]+'0');
puts("");
}
#undef BUF_SIZE
};
using namespace fastIO;
int g[maxn],sum[maxn];
int prime[maxn],mu[maxn];
bool vis[maxn];
void Mobius(int N){
mu[1] = 1;
int tot = 0;
for(int i=2;i<=N;i++){
if(!vis[i]){
prime[tot ++] = i;
mu[i] = -1;
}
for(int j=0;j<tot&&i*prime[j]<=N;j++){
vis[i * prime[j]] = true;
if(i % prime[j] == 0)break;
mu[i * prime[j]] = -mu[i];
}
}
rep(i,0,tot){
for(int j=1;j*prime[i]<=N;j++){
g[j*prime[i]]+=mu[j];
}
// printf("I;:%d\n",i);
}
rep(i,1,maxn)sum[i]=sum[i-1]+g[i];
}
/*
2
2 5 1 5 1
1 5 1 5 2
*/
int main(){
Mobius(maxn-1);
int T;
read(T);
while(T--){
int n,m;
read(n),read(m);
if(n>m)swap(n,m);
ll ans=0;
for(int l=1,r;l<=n;l=r+1){
r=min(n/(n/l),m/(m/l));
ans+=1ll*(n/l)*(m/l)*(ll)(sum[r]-sum[l-1]);
}
print(ans);
}
return 0;
}