【代码超详解】POJ 2478 Farey Sequence(欧拉函数线性打表 + 前缀和)

一、题目描述

【代码超详解】POJ 2478 Farey Sequence(欧拉函数线性打表 + 前缀和)

二、算法分析说明与代码编写指导

观察,写出递推式 F[n] = F[n - 1] ∪ { i / n | gcd(i, n) = 1 }。可见 |F[n]| = |F[n - 1]| + φ(n),认为 φ(1) = 0。
【代码超详解】POJ 2478 Farey Sequence(欧拉函数线性打表 + 前缀和)打表生成 1 ~ 1e6 的欧拉函数的值后,记 S[n] = φ(1) + φ(2) + … + φ(n),求得前缀和。

三、AC 代码(266 ms)

#include<cstdio>
#pragma warning(disable:4996)
unsigned long long phi[1000001], n, s[1000001];
template<class _Pty> inline void gen_phi(_Pty* const phi, const _Pty& n) {
	_Pty m = n / 2;
	for (_Pty i = 2; i <= m; ++i) {
		if (!phi[i]) {
			for (_Pty j = i; j <= n; j += i) {
				if (!phi[j])phi[j] = j;
				phi[j] = phi[j] / i * (i - 1);
			}
		}
	}
	for (_Pty i = m + 1; i <= n; ++i)
		if (!phi[i]) { phi[i] = i - 1; }
}
int main() {
	gen_phi(phi, 1000000ull);
	for (unsigned i = 1; i <= 1000000; ++i)s[i] = s[i - 1] + phi[i];
	for (;;) {
		scanf("%llu", &n); if (n == 0)return 0;
		printf("%llu\n", s[n]);
	}
}
上一篇:一维常物性无源对流导热微分方程数值解(大概)


下一篇:HDU 5634 Rikka with Phi