P2257 YY的GCD

Posted tongseli

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P2257 YY的GCD相关的知识,希望对你有一定的参考价值。

题目描述

神犇YY虐完数论后给傻×kAc出了一题

给定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)为质数的(x, y)有多少对

kAc这种傻×必然不会了,于是向你来请教……

多组输入

输入格式

第一行一个整数T 表述数据组数

接下来T行,每行两个正整数,表示N, M

输出格式

T行,每行一个整数表示第i组数据的结果

说明/提示

T = 10000
N, M <= 10000000

输入输出样例

输入

2
10 10
100 100

输出

30
2791

这道题类似P3455[POI2007]ZAP-Queries

本题其实是求解

[sumlimits_{pin prime}sumlimits_{x=1}^Nsumlimits_{y=1}^M[gcd(x,y)==p]]

大概就是看见([gcd(x,y)==p]) 就想到([gcd(x,y)==1]) 可以变成(I=mu *u)

[sumlimits_{pin prime}sumlimits_{x=1}^{N/p}sumlimits_{y=1}^{M/p}[gcd(x,y)==1]]

[sumlimits_{pin prime}sumlimits_{x=1}^{N/p}sumlimits_{y=1}^{M/p}sumlimits_{d|gcd(x,y)}mu(d)]

然后整除变枚举

[sumlimits_{pin prime}sumlimits_{x=1}^{N/p}sumlimits_{y=1}^{M/p}sumlimits_{d=1}^{min(N/p,M/p)}mu(d)[d|gcd(x,y)]]

[sumlimits_{pin prime}sumlimits_{d=1}^{min(N/p,M/p)}mu(d)sumlimits_{x=1}^{N/p}sumlimits_{y=1}^{M/p}[d|gcd(x,y)]]

要想(d|gcd(x,y)) ,当且仅当,(d) 同时是 (x,y) 的公因子

(lfloorfrac{N}{d} floor)里有(lfloorfrac{N}{dp} floor)(d) 的倍数,同理,(lfloorfrac{M}{d} floor)里有(lfloorfrac{M}{dp} floor)(d) 的倍数

乘法公式,总共就有(lfloorfrac{N}{dp} floorlfloorfrac{M}{dp} floor),就能化简成

[sumlimits_{pin prime}sumlimits_{d=1}^{min(N/p,M/p)}mu(d)lfloorfrac{N}{dp} floorlfloorfrac{M}{dp} floor]

奇思妙想一下,更换一下枚举,(T=dp),就能敲了

[sumlimits_{T=1}^{min(N,M)}lfloorfrac{N}{T} floorlfloorfrac{M}{T} floorsumlimits_{p|T,pin prime}mu(frac{T}{p})]

前面的是分块,后面的是前缀和变形

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int maxn = 1e7;

int prime[maxn+10];
int vis[maxn+10];
int mu[maxn+10];
int pmu[maxn+10];
ll sum[maxn+10];

void sieve(){
    mu[1]=1;
    int p=0;
    for(int i=2;i<=maxn;i++){
        if(!vis[i]){
            vis[i]=1;
            prime[++p]=i;
            mu[i]=-1;
        }
        for(int j=1;j<=p&&i*prime[j]<=maxn;j++){
            vis[i*prime[j]]=1;
            if(i%prime[j]==0)break;
            else mu[i*prime[j]]=-mu[i];
        }
    }
    for(int i=1;i<=p;i++){
        for(int j=1;j*prime[i]<=maxn;j++){
            pmu[j*prime[i]]+=mu[j];
        }
    }
    for(int i=1;i<=maxn;i++){
        sum[i]=sum[i-1]+(ll)pmu[i];
    }
}

int main(){
    memset(vis,0,sizeof(vis));
    sieve();
    int t,n,m;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        ll ans=0;
        int t=min(n,m);
        int r;
        for(int i=1;i<=t;){
            r=min(n/(n/i),m/(m/i));
            ans+=(ll)(n/i)*(m/i)*(sum[r]-sum[i-1]);

            i=r+1;
        }
        cout<<ans<<endl;
    }
}

以上是关于P2257 YY的GCD的主要内容,如果未能解决你的问题,请参考以下文章

P2257 YY的GCD(莫比乌斯反演)

P2257 YY的GCD莫比乌斯反演

P2257 YY的GCD莫比乌斯反演

P2257 YY的GCD莫比乌斯反演

P2257 YY的GCD

P2257 YY的GCD