数论 莫比乌斯反演 学习笔记

  • Post author:
  • Post category:其他


基础知识

1.欧拉函数

定义 即小于n的正整数中与n互质的数的个数

性质

1.对于素数 f(P) = P – 1;

2.不完全积性函数 f(mn) = f(m) * f(n) 当且仅当(m,n) = 1成立

3.对于一个正整数N的素数幂分解(唯一分解定理)

f(N) = N * (1 – 1/P1) * (1 – 1/P2) * … * (1 – 1/Pn)

4.除了N = 2,f(N)均为偶数

拓展:一个数的所有质因数之和 = euler(n) * n  / 2;

模版:

ll euler(ll n) {
    ll res = n;
    for(ll i = 2;i * i <= n;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;
}

线性筛欧拉函数

void getphi() {
    phi[1] = 1;
    for(int i = 2 ; i <= n; i++) {
        if(!mark[i]) {
            phi[i] = i - 1;
            pri[++tot] = i;
        }
        for(int j = 1; j<= tot ; j++) {
            int x = pri[j];
            if(i * x > n) break;
            mark[i* x] = 1;
            if(i % x == 0) {
                phi[i * x] = phi[i] * x;
                break;
            }
            else phi[i * x] = phi[i] * phi[x];
        }
    }
}

莫比乌斯反演线性筛

//莫比乌斯函数线性筛
int prime[MAXN],prime_tot;
bool prime_tag[MAXN];
int mu[MAXN];
void pre_calc(int lim) {
    mu[1] = 1;
    for(int i = 2;i <= lim; i++) {
        if(!prime_tag[i]) {
            prime[++prime_tot] = i;
            mu[i] = -1;
        }
        for(int j = 1; j<= prime_tot;j++) {
            if(i * prime[j] > lim) break;
            prime_tag[i * prime[j]] = true;
            if(i % prime[j] == 0) mu[i * prime[j]] = 0;
            break;
        }
        else {
            mu[i * prime[j]] = -mu[i];
        }
    }
}

(图自 UESTC ACM)



版权声明:本文为Sensente原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。