概念
莫比乌斯函数 μ ( n ) \mu(n) μ(n),是一个积性函数,定义为:
μ ( n ) = { 1 , n = 1 0 , n i s d i v i s i b l e b y t h e s q u a r e o f a p r i m e n u m b e r ( − 1 ) k , k i s t h e n u m b e r o f p r i m e f a c t o r s o f n \mu(n)=\begin{cases}1,n=1\\ 0,n\;is\;divisible\;by\;the\;square\;of\;a\;prime\;number\\ (-1)^k,k\;is\;the\;number\;of\;prime\;factors\;of\;n \end{cases} μ(n)=⎩
⎨
⎧1,n=10,nisdivisiblebythesquareofaprimenumber(−1)k,kisthenumberofprimefactorsofn
其性质有:一、 ∑ d ∣ n μ ( d ) = [ n = 1 ] \sum_{d|n}\mu(d)=[n=1] ∑d∣nμ(d)=[n=1];二、 μ ∗ 1 = ϵ \mu*1=\epsilon μ∗1=ϵ,其中 ∗ * ∗ 表示狄利克雷卷积, ϵ = [ n = 1 ] \epsilon=[n=1] ϵ=[n=1](其实这条与一等价)
莫比乌斯反演的形式有二:一、设 F ( n ) = ∑ n ∣ m f ( m ) F(n)=\sum_{n|m}f(m) F(n)=∑n∣mf(m),有 f ( n ) = ∑ n ∣ m F ( m ) μ ( m n ) f(n)=\sum_{n|m}F(m)\mu(\frac{m}{n}) f(n)=∑n∣mF(m)μ(nm);二、设 F ( n ) = ∑ m ∣ n f ( m ) F(n)=\sum_{m|n}f(m) F(n)=∑m∣nf(m),有 f ( n ) = ∑ m ∣ n F ( n m ) μ ( m ) = ∑ m ∣ n F ( m ) μ ( n m ) f(n)=\sum_{m|n}F(\frac{n}{m})\mu(m)=\sum_{m|n}F(m)\mu(\frac{n}{m}) f(n)=∑m∣nF(mn)μ(m)=∑m∣nF(m)μ(mn);
例题
1. Luogu P2257 YY的GCD
题意
给定 N , M N, M N,M,求 1 ≤ x ≤ n 1 \leq x \leq n 1≤x≤n, 1 ≤ y ≤ m 1 \leq y \leq m 1≤y≤m 且 gcd ( x , y ) \gcd(x, y) gcd(x,y) 为质数的 ( x , y ) (x, y) (x,y) 有多少对。
T = 1 0 4 ; n , m ≤ 1 0 7 T = 10^4;\;n, m \leq 10^7 T=104;n,m≤107。
做法
设 f ( p ) = ∑ x = 1 n ∑ y = 1 m [ gcd ( x , y ) = p ] ; F ( p ) = ∑ p ∣ q f ( q ) = ⌊ n p ⌋ ⌊ m p ⌋ ; L = min ( n , m ) f(p)=\sum_{x=1}^n\sum_{y=1}^m[\gcd(x, y)=p]; F(p)=\sum_{p|q}f(q)=\lfloor\frac{n}{p}\rfloor\lfloor\frac{m}{p}\rfloor; L=\min(n,m) f(p)=∑x=1n∑y=1m[gcd(x,y)=p];F(p)=∑p∣qf(q)=⌊pn⌋⌊pm⌋;L=min(n,m)。
即求:
∑ p ∈ P r i m e f ( p ) = ∑ p ∈ P r i m e ∑ p ∣ x F ( x ) μ ( x p ) = ∑ p ∈ P r i m e ∑ i = 1 L / p ⌊ n i p ⌋ ⌊ m i p ⌋ μ ( i ) = ∑ T = 1 L ⌊ n T ⌋ ⌊ m T ⌋ ∑ p ∣ T & p ∈ P r i m e μ ( T p ) \sum_{p\in Prime}f(p)\\ =\sum_{p\in Prime}\sum_{p|x}F(x)\mu(\frac{x}{p})\\ =\sum_{p\in Prime}\sum_{i=1}^{L/p}\lfloor\frac{n}{ip}\rfloor\lfloor\frac{m}{ip}\rfloor\mu(i)\\ =\sum_{T=1}^{L}\lfloor\frac{n}{T}\rfloor\lfloor\frac{m}{T}\rfloor\sum_{p|T\;\&\;p\in Prime}\mu(\frac{T}{p}) p∈Prime∑f(p)=p∈Prime∑p∣x∑F(x)μ(px)=p∈Prime∑i=1∑L/p⌊ipn⌋⌊ipm⌋μ(i)=T=1∑L⌊Tn⌋⌊Tm⌋p∣T&p∈Prime∑μ(pT)
重点在于求 g ( x ) ≜ ∑ p ∣ x & p ∈ P r i m e μ ( x p ) g(x)\triangleq\sum_{p|x\;\&\;p\in Prime}\mu(\frac{x}{p}) g(x)≜∑p∣x&p∈Primeμ(px)。 p p p 是 x x x 的一个质因数,考虑通过某种顺序枚举 x x x 的质因数,发现线性筛的过程会将 x x x 拆成一个最小的质因数和另一个数的乘积,即 x = y ⋅ p , p ∈ P r i m e x=y\cdot p,\;p\in Prime x=y⋅p,p∈Prime,则有:
g ( x ) = { μ ( 1 ) , x ∈ P r i m e g ( y ) , p i s a f a c t o r o f y − g ( y ) + μ ( y ) , p i s n o t a f a c t o r o f y g(x)=\begin{cases}\mu(1),\;x\in Prime\\ g(y),\;p\;is\;a\;factor\;of\;y\\ -g(y)+\mu(y),\;p\;is\;not\;a\;factor\;of\;y\;\end{cases} g(x)=⎩
⎨
⎧μ(1),x∈Primeg(y),pisafactorofy−g(y)+μ(y),pisnotafactorofy
需要注意从 − g ( y ) -g(y) −g(y) 转移因为 g ( y ) g(y) g(y) 所包含的 μ \mu μ 与 g ( x ) g(x) g(x) 所包含的 μ \mu μ 差一个因子 p p p。
代码
#include <bits/stdc++.h>
const int N = 1e7;
int mu[N + 2], prime[N + 2], top, sum[N + 2];
bool nprime[N + 2];
void solve() {
int n, m;
std::cin >> n >> m;
long long ans = 0;
for (int l = 1, r; l <= std::min(n, m); l = r + 1) {
r = std::min(n / (n / l), m / (m / l));
ans += 1ll * (n / l) * (m / l) * (sum[r] - sum[l - 1]);
}
std::cout << ans << '\n';
}
int main() {
std::ios::sync_with_stdio(0);
std::cin.tie(0);
std::cout.tie(0);
mu[1] = 1;
for (int i = 2; i <= N; i++) {
if (!nprime[i]) {
prime[++top] = i;
mu[i] = -1;
sum[i] = 1;
}
for (int j = 1; j <= top && 1ll * i * prime[j] <= N; j++) {
int now = i * prime[j];
nprime[now] = 1;
if (i % prime[j] == 0) {
mu[now] = 0;
sum[now] = mu[i];
break;
}
mu[now] = -mu[i];
sum[now] = mu[i] - sum[i];
}
}
for (int i = 1; i <= N; i++) {
sum[i] += sum[i - 1];
}
int t;
std::cin >> t;
while (t--) {
solve();
}
}
2. Luogu P2522 [HAOI2011] Problem b
题意
对于给出的 n n n 个询问,每次求有多少个数对 ( x , y ) (x,y) (x,y),满足 a ≤ x ≤ b a \le x \le b a≤x≤b, c ≤ y ≤ d c \le y \le d c≤y≤d,且 gcd ( x , y ) = k \gcd(x,y) = k gcd(x,y)=k。
1 ≤ n , k ≤ 5 × 1 0 4 1 \le n,k \le 5 \times 10^4 1≤n,k≤5×104, 1 ≤ a ≤ b ≤ 5 × 1 0 4 1 \le a \le b \le 5 \times 10^4 1≤a≤b≤5×104, 1 ≤ c ≤ d ≤ 5 × 1 0 4 1 \le c \le d \le 5 \times 10^4 1≤c≤d≤5×104。
做法
(这个感觉比上面一个更加板子)
可以 a ′ ← ⌈ a k ⌉ , b ′ ← ⌊ b k ⌋ a'\gets\lceil\frac{a}{k}\rceil,\;b'\gets\lfloor\frac{b}{k}\rfloor a′←⌈ka⌉,b′←⌊kb⌋ 这样操作把 k k k 转换为 1 1 1,然后对于两个区间可以容斥为 r e s ( b ′ , d ′ ) − r e s ( a ′ − 1 , d ′ ) − r e s ( b ′ , c ′ − 1 ) + r e s ( a ′ − 1 , c ′ − 1 ) res(b',d')-res(a'-1,d')-res(b',c'-1)+res(a'-1,c'-1) res(b′,d′)−res(a′−1,d′)−res(b′,c′−1)+res(a′−1,c′−1)。即求 ∑ x = 1 n ∑ y = 1 m [ gcd ( x , y ) = 1 ] = ∑ i = 1 min ( n , m ) ⌊ n i ⌋ ⌊ m i ⌋ μ ( i ) \sum_{x=1}^{n}\sum_{y=1}^{m}{[\gcd(x,y)=1]}=\sum_{i=1}^{\min(n,m)}\lfloor\frac{n}{i}\rfloor\lfloor\frac{m}{i}\rfloor\mu(i) ∑x=1n∑y=1m[gcd(x,y)=1]=∑i=1min(n,m)⌊in⌋⌊im⌋μ(i)。
代码
#include <bits/stdc++.h>
const int N = 5e4;
int mu[N + 2], prime[N + 2], top, sum[N + 2];
bool nprime[N + 2];
long long work(int n, int m) {
long long ans = 0;
if (n > m) {
std::swap(n, m);
}
for (int l = 1, r; l <= n; l = r + 1) {
r = std::min(n / (n / l), m / (m / l));
ans += 1ll * (n / l) * (m / l) * (sum[r] - sum[l - 1]);
}
return ans;
}
void solve() {
int a, b, c, d, k;
std::cin >> a >> b >> c >> d >> k;
a = (a + k - 1) / k;
c = (c + k - 1) / k;
b = b / k;
d = d / k;
std::cout << (work(b, d) - work(a - 1, d) - work(b, c - 1) + work(a - 1, c - 1)) << '\n';
}
int main() {
std::ios::sync_with_stdio(0);
std::cin.tie(0);
std::cout.tie(0);
mu[1] = 1;
for (int i = 2; i <= N; i++) {
if (!nprime[i]) {
prime[++top] = i;
mu[i] = -1;
}
for (int j = 1; j <= top && 1ll * i * prime[j] <= N; j++) {
int now = i * prime[j];
nprime[now] = 1;
if (i % prime[j] == 0) {
mu[now] = 0;
break;
}
mu[now] = -mu[i];
}
}
for (int i = 1; i <= N; i++) {
sum[i] = sum[i - 1] + mu[i];
}
int t;
std::cin >> t;
while (t--) {
solve();
}
}