bzoj2818GCD

2818: Gcd

Time Limit: 10 Sec   Memory Limit: 256 MB
Submit: 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 
#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;
}


你可能感兴趣的:(#,欧拉函数)