BZOJ原题地址
洛谷原题地址
题目描述
给定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)为质数的(x, y)有多少对。
输入输出
输入格式
第一行一个整数T 表述数据组数。
接下来T行,每行两个正整数,表示N, M。
输出格式
T行,每行一个整数表示第i组数据的结果
样例
输入
2
10 10
100 100
输出
30
2791
思路
我们要求的是 $sum_{i=1}^{n}sum_{j=1}^{m}[gcd(x,y)=prime]$。
然后。。。
坑。
代码
#include
#define maxn 10001000
#define ll long long
using namespace std;
bool vis[maxn];
ll s[maxn];
int pri[maxn],top;
int mu[maxn],g[maxn];
void Init(int n){
mu[1]=1;
for (int i=2;i<=n;++i){
if (!vis[i]) mu[i]=-1,pri[++top]=i;
for (int j=1;j<=top&&pri[j]*i<=n;++j){
vis[i*pri[j]]=1;
if (i%pri[j]==0) break;
mu[pri[j]*i]=-mu[i];
}
}
for (int j=1;j<=top;j++)
for (int i=1;i*pri[j]<=n;i++)
g[i*pri[j]]+=mu[i];
for (int i=1;i<=n;i++)
s[i]=s[i-1]+(ll)g[i];
}
int main(){
ios::sync_with_stdio(false);
Init(maxn-1);
int T;cin>>T;while(T--){
int n,m;
cin>>n>>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+=(ll)(n/l)*(m/l)*(s[r]-s[l-1]);
}
cout<