Farey 序列 F_n 定義為:所有分母 ≤ n、分子分母互質的真分數 a/b (0 < a < b ≤ n),按值升序排列。求 F_n 中項數 N(n)。
例如:F_5 = {1/5, 1/4, 1/3, 2/5, 1/2, 3/5, 2/3, 3/4, 4/5},共 9 項。
N(n) = Σ_{b=2}^n φ(b),其中 φ(b) 是歐拉函數(1~b 中與 b 互質的數的個數)。
證明:對每個分母 b,合法分子數恰為 φ(b)。
#include <cstdio>
const int MAXN = 1000000;
int phi[MAXN + 1];
long long sumPhi[MAXN + 1]; // 前綴和
void linearSievePhi() {
static int primes[MAXN];
static bool isComp[MAXN + 1];
int cnt = 0;
phi[1] = 1;
for (int i = 2; i <= MAXN; ++i) {
if (!isComp[i]) {
primes[cnt++] = i;
phi[i] = i - 1;
}
for (int j = 0; j < cnt && i * primes[j] <= MAXN; ++j) {
int p = primes[j];
int ip = i * p;
isComp[ip] = true;
if (i % p == 0) {
phi[ip] = phi[i] * p;
break;
} else {
phi[ip] = phi[i] * (p - 1);
}
}
}
// 前綴和
for (int i = 1; i <= MAXN; ++i)
sumPhi[i] = sumPhi[i - 1] + phi[i];
}
int main() {
linearSievePhi();
int n;
while (scanf("%d", &n) == 1 && n) {
printf("%lld\n", sumPhi[n]);
}
return 0;
}
long long / %lld| n | N(n) | 近似值 |
|---|---|---|
| 10 | 31 | ~ 3n²/π² |
| 100 | 3043 | ~ 0.304 n² |
| 1000 | 304191 | |
| 10^6 | 303963552391 | ~ 3e11 |