P3957YY的GCD
問題描述
神犇YY虐完數論後給傻×kAc出了一題
給定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)爲質數的(x, y)有多少對
kAc這種傻×必然不會了,於是向你來請教……
輸入格式
第一行一個整數T 表述數據組數
接下來T行,每行兩個正整數,表示N, M
輸出格式
T行,每行一個整數表示第i組數據的結果
樣例輸入
2
10 10
100 100
樣例輸出
30
2791
提示
T = 10000
N, M <= 10000000
顯然
如果是單組詢問,到這裏已經可以了,但本題有多組詢問,因此
後面的部分可以直接枚舉質數再枚舉倍數預處理,複雜度接近
但顯然可以線性篩處理,令其爲 ,當 時, ,否則
然後分塊處理即可,複雜度
代碼:
#include<stdio.h>
#include<algorithm>
#define N 10000005
#define ll long long
using namespace std;
ll T,P[N],tot,mu[N],g[N];
bool mark[N];
void EU()
{
ll i,j;mu[1]=1;g[1]=0;
for(i=2;i<N;i++)
{
if(!mark[i])P[++tot]=i,mu[i]=-1,g[i]=1;
for(j=1;j<=tot&&i*P[j]<N;j++)
if(i%P[j])mu[i*P[j]]=-mu[i],g[i*P[j]]=mu[i]-g[i],mark[i*P[j]]=1;
else {mu[i*P[j]]=0;g[i*P[j]]=mu[i];mark[i*P[j]]=1;break;}
}
for(i=2;i<N;i++)g[i]+=g[i-1];
}
int main()
{
ll n,m,i,j,ans;
scanf("%lld",&T);EU();
while(T--)
{
scanf("%lld%lld",&n,&m);ans=0;
for(i=1;i<=n&&i<=m;i=j+1)
{
j=min(n/(n/i),m/(m/i));
ans+=(n/i)*(m/i)*(g[j]-g[i-1]);
}
printf("%lld\n",ans);
}
}