欧拉函数 & 欧拉定理

欧拉函数

(1)公式法求欧拉函数

\(\alpha\)(N) 1 ~ N 中与 N 互质的数的个数。

N = \({p_1}^{\alpha_1}\) \({p_2}^{\alpha_2}\) \(\ldots\) \({p_k}^{\alpha_k}\)

\(\alpha\)(n) = N (1 - \(\frac{1}{p_1}\)) (1 - \(\frac{1}{p_2}\)) \(\ldots\) (1 - \(\frac{1}{p_k}\))

时间复杂度:O(\(\sqrt{n}\))

http://poj.org/problem?id=2407

题意:求 n 的欧拉函数。

#include <cstdio>
#include <iostream>
using namespace std;

const char nl = '\n';

int get_euler(int n){
    int res = n;
    for (int i = 2; i <= n / i; ++i){
        if (n % i == 0){
            res = res / i * (i - 1);    //避免小数而化简
            while (n % i == 0) n /= i;
        }
    }
    if (n > 1) res = res / n * (n - 1);
    return res;
}

int main(){
    ios::sync_with_stdio(false);
//    cin.tie(nullptr);

    int n;
    while (cin >> n && n){
        cout << get_euler(n) << nl;
    }
    return 0;
}

(2)线性筛法 + 欧拉函数

时间复杂度:O(n)

http://acm.hdu.edu.cn/showproblem.php?pid=2824

题意:求 l , r 两数之间的欧拉函数值之和。

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const char nl = '\n';
const int N = 3e6 + 50;

int primes[N], tot;
int phi[N];
bool st[N];

void get_eulers(int n){
    phi[1] = 1;
    for (int i = 2; i <= n; ++i){
        if (!st[i]){
            primes[tot++] = i;
            phi[i] = i - 1;
        }
        for (int j = 0; primes[j] <= n / i; ++j){
            st[i * primes[j]] = true;
            if (i % primes[j] == 0){
                phi[i * primes[j]] = phi[i] * primes[j];
                break;
            }
            phi[i * primes[j]] = phi[i] * (primes[j] - 1);
        }
    }
}

int main(){
    ios::sync_with_stdio(false);
//    cin.tie(nullptr);

    get_eulers(N);

    int l, r;
    while (cin >> l >> r){
        LL sum = 0;
        for (int i = l; i <= r; ++i) sum += phi[i];
        cout << sum << nl;
    }
    return 0;
}

欧拉定理

如果 n 和 a 互质,则 \(a^{\alpha(n)} \equiv 1\ (mod\ n)\)

特别的,费马定理:\({a}^{p-1} \equiv 1\ (mod\ n)\)

posted @ 2021-02-14 00:11  小燃、  阅读(133)  评论(0编辑  收藏  举报