题目描述:
给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对.
1<=N<=10^7
爆搜?死!那怎么办?
我们注意到,Gcd(x,y)=p,那么就有Gcd(x/p,y/p)=1!
于是我们枚举每个p,设F[i]为i以内互质数对的个数
那么F[i]是啥?没错,phi[i]的前缀和!
于是我们用素数筛+欧拉筛算出n以内所有的质数和所有数的欧拉函数,那么就有ans=sigma( F[ N / prime[i] ] )
写完发现连样例都没过。。这时候才发现数对是有序的
于是Neoans=ans*2-cnt
其中cnt是n以内素数的个数
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n;
int prime[700000],top;
bool not_prime[10001000];
long long ans,phi[10001000];
void Linear_Shaker()
{
int i,j;
phi[1]=1;
for(i=2;i<=n;i++)
{
if(!not_prime[i])
{
prime[++top]=i;
phi[i]=i-1;
}
for(j=1;j<=top&&i*prime[j]<=n;j++)
{
not_prime[prime[j]*i]=1;
if(i%prime[j]==0)
{
phi[prime[j]*i]=phi[i]*prime[j];
break;
}
phi[prime[j]*i]=phi[i]*(prime[j]-1);
}
}
}
int main()
{
int i;
cin>>n;
Linear_Shaker();
for(i=1;i<=n;i++)
phi[i]+=phi[i-1];
for(i=1;i<=top;i++)
ans+=phi[ n/prime[i] ];
cout<<ans*2-top<<endl;
}