求欧拉函数值

    科技2023-10-24  99

    欧拉函数

    两个数gcd等于1,即两个数互质1到n中与n互质的数的个数称为欧拉函数记 ϕ ( n ) \phi(n) ϕ(n)算数基本定理: N = p 1 c 1 p 2 c 2 p 3 c 3 p 4 c 4 ⋯ p m c m N=p_1^{c_1}p_2^{c_2}p_3^{c_3}p_4^{c_4}\cdots p_m^{c_m} N=p1c1p2c2p3c3p4c4pmcm ϕ ( n ) = N × p 1 − 1 p 1 × p 2 − 1 p 2 × ⋯ × p m − 1 p m = N × ∏ 质 数 p ∣ N ( 1 − 1 p ) \phi(n)=N\times\frac{p_1-1}{p_1}\times\frac{p_2-1}{p_2}\times\cdots\times\frac{p_m-1}{p_m}=N\times\prod_{质数p|N}{(1-\frac{1}{p})} ϕ(n)=N×p1p11×p2p21××pmpm1=N×pN(1p1)当a、b互质时, ϕ ( a × b ) = ϕ ( a ) × ϕ ( b ) \phi(a\times b)=\phi(a)\times \phi(b) ϕ(a×b)=ϕ(a)×ϕ(b) ,【积性函数】

    [SDOI2008]仪仗队 题目链接

    线性筛素数的同时求出每个数的欧拉函数值

    const int N = 100000 + 10; int phi[N]; int prime[N]; bool vis[N]; //即可以求出素数,还可以求出欧拉函数值 void Euler() { int cnt = 0; phi[1] = 1; for (int i = 2; i < N; i++) { if (vis[i] == false) { prime[cnt++] = i; phi[i] = i - 1; } for (int j = 0; j < cnt && 1LL * prime[j] * i < 1LL * N; j++) { vis[i * prime[j]] = true; if (i % prime[j] == 0) { phi[i * prime[j]] = phi[i] * prime[j]; break; } else { phi[i * prime[j]] = phi[i] * phi[prime[j]]; } } } }

    只筛素数,复杂度 O ( n l o g n ) O(nlogn) O(nlogn)

    int e2[N]; void Euler2() { for (int i = 1; i < N; ++i) { e2[i] = i; } for (int i = 2; i < N; ++i) { if (e2[i] == i) { for (int j = i; j < N; j += i) { e2[j] = e2[j] / i * (i - 1); } } } }

    也可以这么写

    int e3[N]; void Euler3() { memset(e3, 0, sizeof(e3)); e3[1] = 1; for (int i = 2; i < N; ++i) { if (e3[i] == 0) { for (int j = i; j < N; j += i) { if (e3[j] == 0) { e3[j] = j; } e3[j] = e3[j] / i * (i - 1); } } } }
    Processed: 0.016, SQL: 8