【bzoj2820】YY的GCD 莫比乌斯反演

  • Post author:
  • Post category:其他


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

Sample Output

30

2791

HINT

T = 10000

N, M <= 10000000

Source


跟这个一样:


【bzoj2818】Gcd 欧拉函数

不过是多组数据,每组不能O(n)做了…

所以这样:




















p
















































i


<

=



n





















j


<

=



m









g




c


d




(


i


,


j


)


=


p
















=














p
















































i


<

=



n




/




p





















j


<

=



m




/




p









e


(


g




c


d




(


i


,


j


)


)
















=














p
















































i


<

=



n




/




p





















j


<

=



m




/




p





















d






|




i




d






|




j









μ


(


d




)
















=














p
















































d




<

=



m


i


n


(


n




/




p


,


m




/




p


)









μ


(


d




)














i


<

=



n




/




p





















j


<

=



m




/




p









[


d






|




i




d






|




j


]
















=














p
















































d




<

=



m


i


n


(


n




/




p


,


m




/




p


)









μ


(


d




)











n







p


d




























m







p


d



































k


=


p


d




















=














p
















































k


<

=



m


i


n


(


n


,


m


)










p




|




k









μ


(





k






p













)











n






k

























m






k
































f




(


k


)


=














p




|




k










p




































μ


(





k






p













)











所以答案就是




















k


<

=



m


i


n


(


n


,


m


)









f




(


k


)











n






k

























m






k































f




(


k


)











可以筛。

然后就能








O


(






n





















)











回答了。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;

typedef long long LL;

const int SZ = 10000010;
const int MAXN = 10000000;

bool vis[SZ];
int pri[SZ],mu[SZ];
LL f[SZ],sum[SZ];

void shai()
{
    mu[1] = 1;
    int tot = 0;
    for(int i = 2;i <= MAXN;i ++)
    {
        if(!vis[i]) pri[++ tot] = i,mu[i] = -1;
        for(int j = 1,m;j <= tot && (m = i * pri[j]) <= MAXN;j ++)
        {
            vis[m] = 1;
            if(i % pri[j] == 0) { mu[m] = 0; break; }
            else mu[m] = -mu[i];
        }
    }
    for(int i = 1;i <= tot;i ++)
    {
        for(int j = pri[i];j <= MAXN;j += pri[i])
        {
            f[j] += mu[j / pri[i]];
        }
    }
    for(int i = 1;i <= MAXN;i ++)
        sum[i] = sum[i - 1] + f[i];
}

LL ask(int n,int m)
{
    LL ans = 0;
    if(n > m) swap(n,m);
    for(int i = 1,r;i <= n;i = r + 1)
    {
        r = min(n / (n / i),m / (m / i));
        ans += (sum[r] - sum[i - 1]) * (n / i) * (m / i);
    }
    return ans;
}

int main()
{
    int T;
    scanf("%d",&T);
    shai();
    while(T --)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        printf("%lld\n",ask(n,m));
    }
    return 0;
}



版权声明:本文为LOI_DQS原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。