BZOJ2818 GCD(线性筛、最大公约数、欧拉函数递推)

版权声明:个人笔记,仅供复习 https://blog.csdn.net/weixin_41162823/article/details/85322732

题意:

给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对.

输入格式:

        一个整数N

输出格式:

        答案

AC代码:

/*
BZOJ2818
思路:利用欧拉函数、前缀和来减少计算量。 
*/
#include<cstdio>
const int maxn = 1e7+10;
int primes[maxn/10],v[maxn];
long long phi[maxn],sum[maxn];
int main(){
	int cnt = 0;
	phi[1] = 1;
	for(int i = 2;i < maxn;i++){
		if(!v[i]){
			primes[cnt++] = i;
			v[i] = i;
			phi[i] = i-1;
		}
		for(int j = 0;j < cnt;j++){
			if(primes[j] > v[i] || primes[j]*i > maxn) break;
			v[i*primes[j]] = primes[j];
			phi[i*primes[j]] = phi[i]*(i%primes[j]?primes[j]-1:primes[j]);
		}
	}
	long long ans = 0;
	int n;
	scanf("%d",&n);
	sum[0] = phi[0];
	//for(int i = 0;i < 100;i++)	printf("%lld ",phi[i]); 
	for(int i = 1;i < maxn;i++)	sum[i] = sum[i-1]+phi[i];
	for(int i = 0;i < cnt && primes[i] <= n;i++){
		//printf("%lld %lld\n",primes[i],sum[n/primes[i]]);
		ans += sum[n/primes[i]]*2-1;
	}
	printf("%lld\n",ans);
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/weixin_41162823/article/details/85322732