其他分享
首页 > 其他分享> > 【数论】欧拉函数(基本性质、递推法、公式法、线性筛法)

【数论】欧拉函数(基本性质、递推法、公式法、线性筛法)

作者:互联网

文章目录

欧拉函数

注:以下均来自kuangbin的模板

分解质因数法

int Euler(int n)
{
    getFactors(n); // 前面提过的分解质因数
    int ret = n;
    for (int i = 0; i < fatCnt; i++)
        ret = ret / factor[i][0] * (factor[i][0] - 1);
    return ret;
}

递推法

将 φ ( i ) \varphi(i) φ(i) 先置为 i i i ,把 k i ki ki 的原始 φ \varphi φ 乘上这个 i i i 做出的贡献。

过程中, φ \varphi φ 没有赋值说明是素数

int euler[N];
void getEuler()
{
    memset(euler, 0, sizeof(euler));
    euler[1] = 1;
    for (int i = 2; i < N; i++)
        if (!euler[i])
            for (int j = i; j < N; j += i)
            {
                if (!euler[j])
                    euler[j] = j;
                euler[j] = euler[j] / i * (i - 1);
            }
}

求单个欧拉函数

找素因子,用公式

int euler(int n)
{
    int ans = n;
    for (int i = 2; i * i <= n; i++)
        if (n % i == 0)
        {
            ans -= ans / i;
            while (n % i == 0)
                n /= i;
        }
    if (n > 1)
        ans -= ans / n;
    return ans;
}

线性筛

bool check[N + 10];
int phi[N + 10];
int prime[N + 10];
int tot; //素数的个数
void phi_and_prime_table(int N)
{
    memset(check, false, sizeof(check));
    phi[1] = 1;
    tot = 0;
    for (int i = 2; i <= N; i++)
    {
        if (!check[i])
        {
            prime[tot++] = i;
            phi[i] = i - 1;
        }
        for (int j = 0; j < tot; j++)
        {
            if (i * prime[j] > N)
                break;
            check[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] * (prime[j] - 1); // 积性函数
        }
    }
}

标签:prime,phi,筛法,int,互质,varphi,欧拉,递推,euler
来源: https://blog.csdn.net/default012/article/details/123309503