POJ-2478(欧拉函数)

题目:http://poj.org/problem?id=2478

只套模板的话都不懂为什么,希望弄明白为什么才能理解和记忆的更深刻,看了好几位前辈的博客才终于搞懂欧拉函数的证明和求法,多谢以下几位大牛的博文:

1、关于数论中欧拉函数和欧拉定理的简短证明

2、数论的欧拉定理证明 & 欧拉函数公式

3、数论——欧拉函数与相关定理

4、欧拉函数


#include <cstdio>
#define MAX	1000000

typedef long long LL;
LL phi[MAX + 5] = {0};

int main()
{
//step 1: 求出1~MAX范围内所有数的互质数个数,即每个数的欧拉函数
	for(int i = 2; i <= MAX; ++i) phi[i] = i;
	for(int i = 2; i <= MAX; i += 2) phi[i] >>= 1;//用(2-1)/2来更新所有2的倍数
	for(int i = 3; i <= MAX; i += 2){
		if(phi[i] == i){//说明i是一个素数,用(i-1)/i来更新所有i的倍数,相当于逐个遍历每个数的所有质因数
			for(int j = i; j <= MAX; j += i){
				phi[j] = phi[j] / i * (i - 1);
			}
		}
	}
//step 2: 累加,让phi[n]表示[1,n]范围内欧拉函数的和
	for(int i = 3; i <= MAX; ++i) phi[i] += phi[i-1];
//step 3: answer query
	int n;
	while(scanf("%d", &n), n) printf("%lld\n", phi[n]);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值