2818: Gcd
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 3381 Solved: 1492
[ Submit][ Status][ Discuss]
Description
给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的
数对(x,y)有多少对.
Input
一个整数N
Output
如题
Sample Input
Sample Output
HINT
hint
对于样例(2,2),(2,4),(3,3),(4,2)
1<=N<=10^7
Source
sigma(枚举质数p) sigma (i=1..n) sigma(j=1..n) [gcd(i,j)==p]
sigma(枚举质数p) sigma(i=1..n) sigma(j=1..n) [gcd(i/p,j/p)==1]
sigma(枚举质数p) sigma(i=1..[n/p](下取整)) sigma(j=1..[n/p]) [(i,j)==1]
sigma(枚举质数p) sigma(i=1..[n/p](下取整)) sigma(j=1..[n/p]) sigma(d=1..[n/p]) [d/i] [d/j] mu(d)
sigma(枚举质数p) sigma(i=1..[n/p](下取整)) [d/i] sigma(j=1..[n/p]) [d/j] sigma(d=1..[n/p]) mu(d)
sigma(枚举质数p) 设N=n/p sigma(d=1....N) [N/d][N/d](下取整)mu(d)
mu 可以用线性筛来求,sigma(d=1....N) [N/d][N/d] 看到这个就应该想到分块,因为他只有sqrt(N)个取值,那么我们统计mu的前缀和,然后对于[N/d]相同的部分,直接ans+=[N/d][N/d]*(mu[j]-mu[i-1])
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 10000003
#define ll long long
using namespace std;
long long n;
long long p[N],prime[N],mu[N],ans;
void calc()
{
mu[1]=1;
for (ll i=2;i<=n;i++){
if (!p[i])
{
prime[++prime[0]]=i;
mu[i]=-1;
}
for (ll j=1;j<=prime[0];j++)
{
if (prime[j]*i>n) break;
p[prime[j]*i]=1;
if (i%prime[j]==0)
mu[i*prime[j]]=0;
else
mu[i*prime[j]]=-mu[i];
}
mu[i]+=mu[i-1];
}
}
int main()
{
scanf("%lld",&n);
calc();
for (ll l=1;l<=prime[0];l++)
{
if (prime[0]>n) break;
ll k=n/prime[l];
ll j;
for (ll i=1,j=0;i<=k;i=j+1)
{
j=n/(n/i);
ans+=(mu[j]-mu[i-1])*(k/i)*(k/i);
}
}
printf("%lld\n",ans);
return 0;
}