[bzoj] 2820 YY的GCD || 莫比乌斯反演

原题

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


借鉴自黄学长博客
\(\sum_{isprime(p)}\sum^{n}_{x=1}\sum^{m}_{y=1}[gcd(x,y)==p]\)
\(=\sum_{isprime(p)}\sum^{\lfloor \frac{n}{p} \rfloor}_{x=1}\sum^{\lfloor \frac{m}{p} \rfloor}_{y=1}[gcd(x,y)==1]\)
\(=\sum_{isprime(p)}\sum^{\lfloor \frac{n}{p} \rfloor}_{x=1}\sum^{\lfloor \frac{m}{p} \rfloor}_{y=1}\sum_{d|gcd(x,y)}\mu(d)\)
\(\sum_{isprime(p)}\sum^{n/p}_{d=1}\mu(d)*\lfloor \frac{n}{p*d} \rfloor*\lfloor \frac{n}{p*d} \rfloor\)
设pd为k
\(\sum^n_{k=1}\sum_{isprime(p) \oplus p|k}\mu(k/p)*\lfloor \frac{n}{k} \rfloor*\lfloor \frac{n}{k} \rfloor\)
\(\sum^n_{k=1}F(k)\lfloor \frac{n}{k} \rfloor*\lfloor \frac{n}{k} \rfloor\)

#include<cstdio>
#include<algorithm>
#define N 10000000
typedef long long ll;
using namespace std;
int t,n,m,miu[N+10],prime[N+10],tot;
bool notprime[N+10];
ll ans,sum[N+10];

int read()
{
    int ans=0,fu=1;
    char j=getchar();
    for (;j<'0' || j>'9';j=getchar()) if (j=='-') fu=-1;
    for (;j>='0' && j<='9';j=getchar()) ans*=10,ans+=j-'0';
    return ans*fu;
}

void init()
{
    miu[1]=1;
    for (int i=2;i<=N;i++)
    {
	if (!notprime[i]) miu[i]=-1,prime[++tot]=i;
	for (int j=1;j<=tot && i*prime[j]<=N;j++)
	{
	    notprime[i*prime[j]]=1;
	    if (i%prime[j]) miu[i*prime[j]]=-miu[i];
	    else
	    {
		miu[i*prime[j]]=0;
		break;
	    }
	}
    }
    for (int i=1;i<=tot;i++)
	for (int j=prime[i];j<=N;j+=prime[i])
	    sum[j]+=miu[j/prime[i]];
    for (int i=2;i<=N;i++)
	sum[i]+=sum[i-1];
}

int main()
{
    init();
    t=read();
    while (t--)
    {
	n=read();
	m=read();
	ans=0;
	if (n>m) swap(n,m);
	for (int i=1,last;i<=n;i=last+1)
	{
	    last=min(n/(n/i),m/(m/i));
	    ans+=(ll)(n/i)*(m/i)*(sum[last]-sum[i-1]);
	}
	printf("%lld\n",ans);
    }
    return 0;
}
posted @ 2018-01-04 17:30  Mrha  阅读(116)  评论(0编辑  收藏  举报