YY的GCD(莫比烏斯反演)
阿新 • • 發佈:2019-01-23
【題目描述】
神犇YY虐完數論後給傻×kAc出了一題
給定,求且為質數的有多少對
kAc這種傻×必然不會了,於是向你來請教……
多組輸入
【輸入格式】
第一行一個整數T 表述資料組數
接下來T行,每行兩個正整數,表示N, M
【輸出格式】
T行,每行一個整數表示第i組資料的結果
【樣例輸入】
2
10 10
100 100
【樣例輸出】
30
2791
【思路】
貼一篇大佬的題解,太強了 BZOJ2820
本菜雞差不多照貓畫虎抄了一遍程式碼
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=10000005;
bool vis[maxn];
int prim[maxn];
int mu[maxn];
ll g[maxn],sum[maxn];
int cnt;
void get_mu(int n){
mu[1]=1;
for(int i=2;i<=n;i++){
if(!vis[i]){
prim[++cnt]=i;
mu[i]=-1 ;
}
for(int j=1;j<=cnt && prim[j]*i<=n;j++){
vis[prim[j]*i]=1;
if(i%prim[j]==0) break;
else mu[i*prim[j]]=-mu[i];
}
}
for(int j=1;j<=cnt;++j){
for(int i=1;i*prim[j]<=n;++i){
g[i*prim[j]]+=mu[i];
}
}
for (int i=1;i<=n;++i) sum[i]=sum[i-1]+g[i];
}
int main(){
get_mu(maxn-1);
int T;
scanf("%d",&T);
while(T--){
int n,m;
scanf("%d%d",&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+=(sum[R]-sum[L-1])*(ll)(n/L)*(ll)(m/L);
}
printf("%lld\n",ans);
}
return 0;
}