第六章 积性函数(数学)
6.1 笔记
-
积性函数:
-
定义:若函数 f : N → R f:N\rightarrow R f:N→R,满足 ∀ p , q ∈ Z + ( p ≠ q ) \forall p,q\in Z^+(p\ne q) ∀p,q∈Z+(p=q) 且 ( p , q ) = 1 \color{red}(p,q)=1 (p,q)=1,都有 f ( p q ) = f ( p ) f ( q ) f(pq)=f(p)f(q) f(pq)=f(p)f(q),则称 f f f 为积性函数。
-
实例:
- 1 ( n ) = 1 1(n)=1 1(n)=1
- i d ( n ) = n id(n)=n id(n)=n
- ε ( n ) = [ n = 1 ] \varepsilon(n) = [n=1] ε(n)=[n=1]
- φ ( n ) = 1 , . . . , n \varphi(n)=1,...,n φ(n)=1,...,n 中与 n n n 中互质的数的数量
- d ( n ) = n d(n)=n d(n)=n 的正因子的数量
-
性质:若 f ( x ) , g ( x ) f(x),g(x) f(x),g(x) 是积性函数,则 h ( x ) = f ( x ) g ( x ) h(x)=f(x)g(x) h(x)=f(x)g(x) 也是积性函数
-
计算:设 n = p 1 α 1 p 2 α 2 . . . p k α k n=p_1^{\alpha_1}p_2^{\alpha_2}...p_k^{\alpha_k} n=p1α1p2α2...pkαk,则
f ( n ) = f ( p 1 α 1 ) f ( p 2 α 2 ) . . . f ( p k α k ) f(n)=f(p_1^{\alpha_1})f(p_2^{\alpha_2})...f(p_k^{\alpha_k}) f(n)=f(p1α1)f(p2α2)...f(pkαk)
利用质因数分解求 f ( n ) f(n) f(n)ll get_f(ll n){ ll ans = 1; rep(i, 2, n / i){ int cnt = 0; while(n % i == 0) cnt++, n /= i; ans *= f(i, cnt); //f(p, k) = f(p ^ k) } if(n > 1) ans *+ f(n, 1); return ans; }
利用欧拉筛计算 f ( 1 ) , . . . , f ( n ) f(1),...,f(n) f(1),...,f(n)
int primes[N], is_prime[N], f[N], cnt = 0, mfcnt[N]; ll calc_f(ll p, ll k){ ... } void Eoula(int n){ memset(is_prime, 1, sizeof(is_prime)); is_prime[1] = 0, f[1] = 1; rep(mf, 2, n){ if(is_prime[mf]) primes[++cnt] = mf, f[mf] = calc_f(mf, 1), mfcnt[mf] = 1; for(int j = 1; j <= cnt && mf * primes[j] <= n; j++){ is_prime[primes[j] * mf] = 0; if(mf % primes[j] == 0){ mfcnt[primes[j] * mf] = mfcnt[mf] + 1; f[primes[j] * mf] = f[mf] / calc_f(primes[j], mfcnt[mf]) * calc_f(primes[j], mfcnt[mf] + 1); break; } else{ mfcnt[primes[j] * mf] = 1; f[primes[j] * mf] = calc_f(primes[j], 1) * f[mf]; } } } }
-
-
莫比乌斯(Mobius)反演:
引入:已知 f ( n ) = ∑ i = 1 n g ( i ) f(n)=\sum\limits_{i=1}^{n}g(i) f(n)=i=1∑ng(i),则可通过 f f f 计算出 g g g,即 g ( n ) = f ( n ) − f ( n − 1 ) g(n)=f(n)-f(n-1) g(n)=f(n)−f(n−1)
-
已知 f ( n ) = ∑ d ∣ n g ( d ) f(n)=\sum\limits_{d\mid n}g(d) f(n)=d∣n∑g(d),则要通过 f f f 计算出 g g g。
证明:
g ( n ) = g ( p 1 α 1 p 2 α 2 . . . p k α k ) = ∑ S ⊆ { 1 , 2 , . . . , k } ( − 1 ) ∣ S ∣ f ( p 1 α 1 − i 1 p 2 α 2 − i 2 . . . p k α k − i k ) 其 中 i j = { 1 , j ∈ S 0 , j ∉ S 令 μ ( n ) = μ ( p 1 i 1 p 2 i 2 . . . p k i k ) = { ( − 1 ) k , 若 i 1 = i 2 = . . . = i k = 1 0 , o t h e r s \begin{aligned} g(n)=&g(p_1^{\alpha_1}p_2^{\alpha_2}...p_k^{\alpha_k} )\\ =&\sum\limits_{S\subseteq \{1,2,...,k\}}(-1)^{|S|}f(p_1^{\alpha_1-i_1}p_2^{\alpha_2-i_2}...p_k^{\alpha_k-i_k})\qquad其中\;i_j=\begin{cases}1,j\in S\\0,j\notin S \end{cases}\\ 令\;\mu(n)=&\mu(p_1^{i_1}p_2^{i_2}...p_k^{i_k})=\begin{cases}(-1)^k,\quad 若\;i_1=i_2=...=i_k=1 \\0,\qquad others \end{cases} \end{aligned} g(n)==令μ(n)=g(p1α1p2α2...pkαk)S⊆{1,2,...,k}∑(−1)∣S∣f(p1α1−i1p2α2−i2...pkαk−ik)其中ij={1,j∈S0,j∈/Sμ(p1i1p2i2...pkik)={(−1)k,若i1=i2=...=ik=10,others -
莫比乌斯反演:设 f : N → R f:N\rightarrow R f:N→R, g : N → R g:N\rightarrow R g:N→R 是两个函数,则
f ( n ) = ∑ d ∣ n g ( d ) ⟺ g ( n ) = ∑ d ∣ n μ ( n d ) f ( d ) , 其 中 μ ( n ) = { ( − 1 ) k , n 无 平 方 因 子 且 有 k 个 质 因 子 0 , n 有 平 方 因 子 \color{red}f(n)=\sum\limits_{d\mid n}g(d)\iff g(n)=\sum\limits_{d\mid n}\mu(\dfrac{n}{d})f(d),\\ 其中 \mu(n)=\begin{cases}\begin{aligned}&(-1)^k,&&n无平方因子且有k个质因子\\&0,&&n有平方因子 \end{aligned}\end{cases} f(n)=d∣n∑g(d)⟺g(n)=d∣n∑μ(dn)f(d),其中μ(n)={(−1)k,0,n无平方因子且有k个质因子n有平方因子
其中, μ ( x ) \mu(x) μ(x) 为积性函数,可用欧拉筛求int primes[N], is_prime[N], mu[N], cnt = 0; void Euler(int n){ memset(is_prime, 1, sizeof(is_prime)); is_prime[1] = 0, mu[1] = 1; rep(mf, 2, n){ if(is_prime[mf]){ primes[++cnt] = mf; mu[mf] = -1; } for(int j = 1; j <= cnt && mf * primes[j] <= n; j++){ is_prime[primes[j] * mf] = 0; if(mf % primes[j] == 0) break; mu[primes[j] * mf] = -mu[mf]; } } }
-
环计数问题:
-
莫比乌斯反演2:设 f : N → R f:N\rightarrow R f:N→R, g : N → R g:N\rightarrow R g:N→R 是两个函数,且存在正整数 n n n,对于所有 n > N n>N n>N,有 f ( n ) = g ( n ) = 0 f(n)=g(n)=0 f(n)=g(n)=0,则
f ( n ) = ∑ n ∣ m , m ≤ N g ( m ) ⟺ g ( n ) = ∑ n ∣ m , m ≤ N μ ( m n ) f ( m ) \color{red}f(n)=\sum\limits_{n\mid m,m\le N}g(m)\iff g(n)=\sum\limits_{n\mid m, m\le N}\mu\left(\dfrac{m}{n} \right)f(m) f(n)=n∣m,m≤N∑g(m)⟺g(n)=n∣m,m≤N∑μ(nm)f(m)
-
6.2 习题
地址:第六章习题
A. 模板题【线性筛求积性函数】
- 题目链接:模板题【线性筛求积性函数】
- 思路:欧拉筛直接预处理计算
//积性函数筛
#include<bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = (a); i <= (b); i++)
#define per(i, a, b) for(int i = (a); i >= (b); i--)
#define ll long long
#define db double
#define VI vector<int>
#define PII pair<int, int>
const db Pi = 3.141592653589793;
const int INF = 0x7fffffff;
const int N = 1e7 + 5;
const db eps = 1e-10;
int cas, n, m, a[N];
int primes[N], is_prime[N], f[N], cnt = 0, mfcnt[N];
ll calc_f(ll p, ll k){
return k + 1;
}
void getprime(int n){
memset(is_prime, 1, sizeof(is_prime));
is_prime[1] = 0, f[1] = 1;
rep(mf, 2, n){
if(is_prime[mf]) primes[++cnt] = mf, f[mf] = calc_f(mf, 1), mfcnt[mf] = 1;
for(int j = 1; j <= cnt && mf * primes[j] <= n; j++){
is_prime[primes[j] * mf] = 0;
if(mf % primes[j] == 0){
mfcnt[primes[j] * mf] = mfcnt[mf] + 1;
f[primes[j] * mf] = f[mf] / calc_f(primes[j], mfcnt[mf]) * calc_f(primes[j], mfcnt[mf] + 1);
break;
}
else{
mfcnt[primes[j] * mf] = 1;
f[primes[j] * mf] = calc_f(primes[j], 1) * f[mf];
}
}
}
}
int main(){
getprime(10000000);
cin >> cas;
while(cas--){
scanf("%d", &n);
printf("%d\n", f[n]);
}
}
/*
5
1
2
3
4
5
*/
B. 华华给月月出题
-
题目:计算 ⨁ i = 1 n ( i n ( m o d 1 0 9 + 7 ) ) 1 ≤ n ≤ 1.3 × 1 0 7 \bigoplus\limits_{i=1}^{n}(i^n\pmod{10^9+7})\quad 1\le n\le 1.3\times 10^7 i=1⨁n(in(mod109+7))1≤n≤1.3×107
-
思路:由于 f ( i ) = i n f(i)=i^n f(i)=in 为积性函数,即 f ( p q ) = ( p q ) n = p n ⋅ q n = f ( p ) f ( q ) f(pq)=(pq)^n=p^n\cdot q^n=f(p)f(q) f(pq)=(pq)n=pn⋅qn=f(p)f(q)
- 快速幂计算 f ( p ) f(p) f(p):约有 n ln n \dfrac{n}{\ln n} lnnn 个质数,每个快速幂复杂度为 O ( log n ) O(\log n) O(logn)
- 欧拉筛计算 f ( i ) = i n f(i)=i^n f(i)=in:复杂度为 O ( n ) O(n) O(n)
总复杂度为 O ( n ln n log n + n ) ≈ O ( n ) O(\dfrac{n}{\ln n}\log n+n)\approx O(n) O(lnnnlogn+n)≈O(n)
#include<bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = (a); i <= (b); i++)
#define per(i, a, b) for(int i = (a); i >= (b); i--)
#define ll long long
#define db double
#define VI vector<int>
#define PII pair<int, int>
const db Pi = 3.141592653589793;
const int INF = 0x7fffffff;
const int N = 1.3e7 + 5;
const db eps = 1e-10;
const ll mod = 1e9 + 7;
int n, ans;
int primes[N], is_prime[N], f[N], cnt = 0, mfcnt[N];
ll power(ll a, ll b, ll mod){
ll ans = 1;
if(mod == 1) ans = 0;
while(b > 0){
if(b % 2 == 1) (ans *= a) %= mod;
(a *= a) %= mod;
b >>= 1;
}
return ans;
}
void getprime(ll n){
memset(is_prime, 1, sizeof(is_prime));
is_prime[1] = 0, f[1] = 1;
rep(mf, 2, n){
if(is_prime[mf]){
primes[++cnt] = mf;
f[mf] = power(mf, n, mod);
}
for(int j = 1; j <= cnt && mf * primes[j] <= n; j++){
is_prime[primes[j] * mf] = 0;
f[primes[j] * mf] = (ll)f[primes[j]] * f[mf] % mod;
if(mf % primes[j] == 0) break;
}
}
}
int main(){
cin >> n;
getprime(n);
ans = f[1];
rep(i, 2, n) ans = ans ^ f[i];
cout << ans << endl;
}
/*
3
in2
2005117
out2
863466972
*/
C. 序列
-
题目:两个长度为 n n n 的序列,求满足 gcd ( x , y ) = 1 \gcd(x,y)=1 gcd(x,y)=1 且 a b x = b a y a_{b_x}=b_{a_y} abx=bay 的对 ( x , y ) (x,y) (x,y) 的数量。 1 ≤ n ≤ 1 0 5 , 1 ≤ a i , b i ≤ n 1\le n\le 10^5, 1\le a_i,b_i\le n 1≤n≤105,1≤ai,bi≤n
-
知识点:反演
-
思路:求 ∑ 1 ≤ x , y ≤ n [ a b x = b a y ] ⋅ [ gcd ( x , y ) = 1 ] \sum\limits_{1\le x, y\le n}[a_{b_x}=b_{a_y}]\cdot [\gcd(x,y)=1] 1≤x,y≤n∑[abx=bay]⋅[gcd(x,y)=1]
- 设
g
(
d
)
=
∑
1
≤
x
,
y
≤
n
[
a
b
x
=
b
a
y
]
⋅
[
gcd
(
x
,
y
)
=
d
]
g(d)=\sum\limits_{1\le x, y\le n}[a_{b_x}=b_{a_y}]\cdot [\gcd(x,y)=d]
g(d)=1≤x,y≤n∑[abx=bay]⋅[gcd(x,y)=d],则
f ( d ) = ∑ d ∣ d ′ g ( d ′ ) = ∑ d ∣ x , d ∣ y [ a b x = b a y ] ⟺ g ( d ) = ∑ d ∣ d ′ , d ′ ≤ n μ ( d ′ d ) f ( d ′ ) ∴ g ( 1 ) = ∑ d ′ = 1 n μ ( d ′ ) f ( d ′ ) \color{red} f(d)=\sum\limits_{d\mid d'}g(d')=\sum\limits_{d\mid x,d\mid y}[a_{b_x}=b_{a_y}]\iff g(d)=\sum\limits_{d\mid d',d'\le n}\mu(\dfrac{d'}{d})f(d')\\ \therefore g(1)=\sum\limits_{d'=1}^n \mu(d')f(d') f(d)=d∣d′∑g(d′)=d∣x,d∣y∑[abx=bay]⟺g(d)=d∣d′,d′≤n∑μ(dd′)f(d′)∴g(1)=d′=1∑nμ(d′)f(d′)
- 设
g
(
d
)
=
∑
1
≤
x
,
y
≤
n
[
a
b
x
=
b
a
y
]
⋅
[
gcd
(
x
,
y
)
=
d
]
g(d)=\sum\limits_{1\le x, y\le n}[a_{b_x}=b_{a_y}]\cdot [\gcd(x,y)=d]
g(d)=1≤x,y≤n∑[abx=bay]⋅[gcd(x,y)=d],则
#include<bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = (a); i <= (b); i++)
#define per(i, a, b) for(int i = (a); i >= (b); i--)
#define ll long long
#define db double
#define VI vector<int>
#define PII pair<int, int>
const db Pi = 3.141592653589793;
const int INF = 0x7fffffff;
const int N = 1e5 + 5;
const db eps = 1e-10;
int n, a[N], b[N], f[N];
int primes[N], is_prime[N], mu[N], cnt = 0;
ll ans;
void Euler(int n){
memset(is_prime, 1, sizeof(is_prime));
is_prime[1] = 0, mu[1] = 1;
rep(mf, 2, n){
if(is_prime[mf]) primes[++cnt] = mf, mu[mf] = -1;
for(int j = 1; j <= cnt && mf * primes[j] <= n; j++){
is_prime[primes[j] * mf] = 0;
if(mf % primes[j] == 0) break;
mu[primes[j] * mf] = -mu[mf];
}
}
}
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin >> n;
Euler(n);
rep(i, 1, n) cin >> a[i];
rep(i, 1, n) cin >> b[i];
rep(d, 1, n){
memset(f, 0, sizeof(f));
for(int x = d; x <= n; x += d) f[a[b[x]]]++;
for(int y = d; y <= n; y += d) ans += f[b[a[y]]] * mu[d];
}
cout << ans << endl;
}
/*
3
1 1 1
1 1 1
*/