2818: Gcd
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 3249 Solved: 1440
[ Submit][ Status][ Discuss]
Description
给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的
数对(x,y)有多少对.
Input
一个整数N
Output
如题
Sample Input
4
Sample Output
4
HINT
hint
对于样例(2,2),(2,4),(3,3),(4,2)
1<=N<=10^7
Source
分析
求[1,n]中gcd(x,y)为质数的个数,先枚举[1,n]中的素数,对于each p(p素数),只需在[1,n/p]中找gcd(x',y')=1的数对个数,不妨设x'≤y',那么对于each y'(y'∈[1,n/p]),小于等于它且与它互质的数的个数为欧拉函数φ(y'),我们把所有的φ(y)加起来再乘2,就得到了当p一定时的答案,其中 可以用前缀和处理。另外x'=1,y'=1的情况也是合法的,我们乘2以后的答案包含了两个(1,1),所以应该减去1。
求φ时间复杂度O(N),统计
时间复杂度
O(N),总的是O(N)。
代码
#include <cstdio>
#define maxn 10000010
#define maxp 700000
using namespace std;
long long N, phi[maxn], s[maxn], tot, p[maxp], ans;
void oula()
{
int i, j;
for(i=1;i<=N;i++)phi[i]=i;
for(i=2;i<=N;i++)
{
if(phi[i]==i)
{
p[++tot]=i;
for(j=i;j<=N;j+=i)phi[j]=phi[j]-phi[j]/i;
}
}
for(i=1;i<=N;i++)s[i]=s[i-1]+phi[i];
}
int main()
{
int i, j;
scanf("%d",&N);
oula();
for(i=1;i<=tot;i++)
ans=ans+(s[N/p[i]]<<1)-1;
printf("%lld\n",ans);
return 0;
}