2820: YY的GCD
Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 2047 Solved: 1091
[Submit][Status][Discuss]
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
莫比乌斯反演重修第二弹
粘的popoqqq的PPT
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<complex>
#include<iostream>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<string>
#include<bitset>
#include<queue>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=10*x+ch-'0';ch=getchar();}
return x*f;
}
inline void print(ll x)
{if(x<0)putchar('-'),x=-x;if(x>=10)print(x/10);putchar('0'+x%10);}
const int N=10000100;
bool book[N];
int prime[N],mobius[N];
ll sum[N];
void initial()
{
mobius[1]=1;int cnt=0;
for(int i=2;i<N;i++)
{
if(!book[i]){prime[++cnt]=i;mobius[i]=-1;}
for(int j=1,now;j<=cnt&&prime[j]*i<N;j++)
{
now=prime[j]*i;book[now]=1;mobius[now]=-mobius[i];
if(i%prime[j]==0){mobius[now]=0;break;}
}
}
for(int i=1;i<=cnt;++i)for(int j=1;j*prime[i]<N;++j)
sum[prime[i]*j]+=mobius[j];
for(int i=1;i<N;++i)sum[i]+=sum[i-1];
}
inline void solve(int n,int m)
{
ll ans=0;if(n>m)swap(n,m);
for(int i=1,j;i<=n;i=j+1)
{
j=min(n/(n/i),m/(m/i));
ans+=(sum[j]-sum[i-1])*(n/i)*(m/i);
}
print(ans);puts("");
}
int main()
{
initial();int T=read();
while(T--){int n=read(),m=read();solve(n,m);}
return 0;
}
/*
2
10 10
100 100
30
2791
*/