基礎知識
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)