莫比乌斯反演学习(来自PoPoQQQ)

莫比乌斯反演有什么作用?
对于一些函数 f ( n ) f(n) f(n),如果我们很难直接求出它的值,而容易求出倍数和或约数和 F ( n ) F(n) F(n),那么我们可以通过莫比乌斯反演来求得 f ( n ) f(n) f(n) 的值。

引子

首先来看一个函数: F ( n ) = ∑ d ∣ n f ( d ) F(n) = \sum_{d|n}f(d) F(n)=dnf(d)
根据F函数的定义,可以得到:
F ( 1 ) = f ( 1 ) F(1) = f(1) F(1)=f(1) F ( 2 ) = f ( 1 ) + f ( 2 ) F(2) = f(1) + f(2) F(2)=f(1)+f(2) F ( 3 ) = f ( 1 ) + f ( 3 ) F(3) = f(1) + f(3) F(3)=f(1)+f(3) F ( 4 ) = f ( 1 ) + f ( 2 ) + f ( 4 ) F(4) = f(1) + f(2) + f(4) F(4)=f(1)+f(2)+f(4) F ( 5 ) = f ( 1 ) + f ( 5 ) F(5) = f(1) + f(5) F(5)=f(1)+f(5) F ( 6 ) = f ( 1 ) + f ( 2 ) + f ( 3 ) + f ( 6 ) F(6) = f(1) + f(2) + f(3) + f(6) F(6)=f(1)+f(2)+f(3)+f(6)

如果我们已知 F ( n ) F(n) F(n) 我们可以通过反推求出 f ( n ) f(n) f(n)
f ( 1 ) = F ( 1 ) f(1) = F(1) f(1)=F(1) f ( 2 ) = F ( 2 ) − F ( 1 ) f(2) = F(2) - F(1) f(2)=F(2)F(1) f ( 3 ) = F ( 3 ) − F ( 1 ) f(3) = F(3) - F(1) f(3)=F(3)F(1) f ( 4 ) = F ( 4 ) − F ( 2 ) f(4) = F(4) - F(2) f(4)=F(4)F(2) f ( 5 ) = F ( 5 ) − F ( 1 ) f(5) = F(5) - F(1) f(5)=F(5)F(1) f ( 6 ) = F ( 6 ) − F ( 3 ) − F ( 2 ) + F ( 1 ) f(6) = F(6) - F(3) - F(2) + F(1) f(6)=F(6)F(3)F(2)+F(1)

在这个反推的过程中存在一些规律,总结起来公式如下: F ( n ) = ∑ d ∣ n f ( d ) − − > f ( n ) = ∑ d ∣ n u ( d ) F ( n d ) F(n) = \sum_{d|n}f(d) -->f(n) = \sum_{d|n}u(d)F(\frac{n}{d}) F(n)=dnf(d)>f(n)=dnu(d)F(dn)

其中的 u ( d ) u(d) u(d)就是莫比乌斯函数。

莫比乌斯函数 u ( d ) u(d) u(d)

函数定义:
u ( d ) = { 1 ( d = 1 ) ( − 1 ) k ( d = p 1 p 2 p 3 ⋯ p k ) 0 ( o t h e r s ) u(d) = \begin{cases} 1 & (d=1)\\ (-1)^k & (d = p_1p_2p_3 \cdots p_k) \\ 0 & (others) \end{cases} u(d)=1(1)k0(d=1)(d=p1p2p3pk)(others)

函数性质

  1. 对于任意正整数n有
    ∑ d ∣ n u ( d ) = { 1 ( n = 1 ) 0 ( n > 1 ) \sum_{d|n}u(d) = \begin{cases} 1 & (n = 1)\\ 0 & (n > 1) \end{cases} dnu(d)={10(n=1)(n>1)
    证明:
    1. 若n = 1,那么显然成立;
    2. 若n ≠ 1,那么n一定可以分解得到 n = p 1 a 1 ⋯ p k a k n = p_1^{a1} \cdots p_k^{ak} n=p1a1pkak
      因此在n的所有因子中,当且仅当该因子的所有质因子次数均为1时u值不为零。其中,质因子个数为r个的因子有 C k r C_k^r Ckr个。
      那么显然 ∑ d ∣ n u ( d ) = C k 0 − C k 1 + C k 2 + ⋯ + ( − 1 ) k C k k = ∑ i = 0 k ( − 1 ) i C k i \sum_{d|n}u(d) = C_k^0 - C_k^1 + C_k^2 + \cdots + (-1)^kC_k^k = \sum^k_{i=0} (-1)^iC_k^i dnu(d)=Ck0Ck1+Ck2++(1)kCkk=i=0k(1)iCki
      又因为二项式定理 ( x + y ) n = ∑ i = 0 n C n i x i y n − i (x+y)^n = \sum^n_{i=0}C^i_nx^iy^{n-i} (x+y)n=i=0nCnixiyni
      所以令 x = − 1 , y = 1 x = -1, y = 1 x=1,y=1,代入,证明完毕。
      _
  2. 积性函数
    数论中积性函数的定义:
    f ( n ) f(n) f(n) 为一个定义在 N + N^+ N+ 集合上的函数,如果对于任意的 ( x , y ) = 1 (x, y)=1 (x,y)=1 f ( x y ) = f ( x ) ∗ f ( y ) f(xy)=f(x)*f(y) f(xy)=f(x)f(y),则称 f ( n ) f(n) f(n) 为一个 积性函数
    若对于任意x和y均有 f ( x y ) = f ( x ) ∗ f ( y ) f(xy)=f(x)*f(y) f(xy)=f(x)f(y) ,则称 f ( n ) f(n) f(n) 为一个 完全积性函数。
    积性函数的性质
    1. f ( 1 ) = 1 f(1) = 1 f(1)=1
    2. 积性函数的前缀和也是积性函数;
      _
  3. (不重要)对任意正整数n有: ∑ d ∣ n u ( d ) d = ϕ ( n ) n \sum_{d|n} \frac{u(d)}{d} = \frac{\phi(n)}{n} dndu(d)=nϕ(n)
    证明:
    只需要令 F ( n ) = n , f ( n ) = ϕ ( n ) F(n) = n,f(n) = \phi (n) F(n)=n,f(n)=ϕ(n)代入莫比乌斯反演公式即可。

Mobius函数代码
由于莫比乌斯函数是积性函数,因此可以通过线性筛来求出莫比乌斯函数的值

const int N = 100000;
bool check[N+10];
int prime[N+10];
int mu[N+10];
void Moblus() {
   memset(check,false,sizeof(check));
   mu[1] = 1;
   int tot = 0;
   for(int i = 2; i <= N; i++) {
      if( !check[i] ) {
         prime[tot++] = i;
         mu[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)  {
            mu[i * prime[j]] = 0;
            break;
         } else {
            mu[i * prime[j]] = -mu[i];
         }
      }
   }
}

莫比乌斯反演

形式一
F ( n ) = ∑ d ∣ n f ( d ) − − > f ( n ) = ∑ d ∣ n u ( d ) F ( n d ) F(n) = \sum_{d|n}f(d) -->f(n) = \sum_{d|n}u(d)F(\frac{n}{d}) F(n)=dnf(d)>f(n)=dnu(d)F(dn)

证明:
对原式做数论变换:
∑ d ∣ n u ( d ) F ( n d ) = ∑ d ∣ n u ( d ) ∑ d ∣ n k f ( k ) = ∑ k ∣ n f ( k ) ∑ d ∣ n k u ( d ) \sum_{d|n}u(d)F(\frac{n}{d}) = \sum_{d|n}u(d)\sum_{d|\frac{n}{k}}f(k) = \sum_{k|n}f(k)\sum_{d|\frac{n}{k}}u(d) dnu(d)F(dn)=dnu(d)dknf(k)=knf(k)dknu(d)
根据莫比乌斯函数性质,有
∑ d ∣ n u ( d ) = { 1 ( n = 1 ) 0 ( n > 1 ) \sum_{d|n}u(d) = \begin{cases} 1 & (n = 1)\\ 0 & (n > 1) \end{cases} dnu(d)={10(n=1)(n>1)
因此当且仅当 n k = 1 \frac{n}{k} = 1 kn=1时,即n=k时, ∑ d ∣ n k u ( d ) = 1 \sum_{d|\frac{n}{k}}u(d)=1 dknu(d)=1,否则为0.
所以 ∑ k ∣ n f ( k ) ∑ d ∣ n k u ( d ) = f ( n ) \sum_{k|n}f(k)\sum_{d|\frac{n}{k}}u(d) = f(n) knf(k)dknu(d)=f(n)

形式二
F ( n ) = ∑ n ∣ d f ( d ) − − > f ( n ) = ∑ n ∣ d u ( d n ) F ( d ) F(n) = \sum_{n|d}f(d) -->f(n) = \sum_{n|d}u(\frac{d}{n})F(d) F(n)=ndf(d)>f(n)=ndu(nd)F(d)

证明
与形式一同理
∑ n ∣ d u ( d n ) F ( d ) = ∑ k = 1 + ∞ u ( k ) f ( n k ) = ∑ k = 1 + ∞ u ( k ) ∑ n k ∣ t f ( t ) = ∑ n ∣ t f ( t ) ∑ k ∣ t n u ( k ) \sum_{n|d}u(\frac{d}{n})F(d) = \sum_{k=1}^{+∞}u(k)f(nk) = \sum_{k=1}^{+∞}u(k)\sum_{nk|t}f(t) = \sum_{n|t}f(t)\sum_{k|\frac{t}{n}}u(k) ndu(nd)F(d)=k=1+u(k)f(nk)=k=1+u(k)nktf(t)=ntf(t)kntu(k)
同理当且仅当 t n = 1 \frac{t}{n} = 1 nt=1时,即t=n时, ∑ k ∣ t n u ( k ) = 1 \sum_{k|\frac{t}{n}}u(k)=1 kntu(k)=1,否则为0.
最终得到
∑ n ∣ t f ( t ) ∑ k ∣ t n u ( k ) = f ( n ) \sum_{n|t}f(t)\sum_{k|\frac{t}{n}}u(k) = f(n) ntf(t)kntu(k)=f(n)
证毕。
卷积证明自己了解。

应用

BZOJ2301(所有教程都有的经典例题)

题意:
对于给出的 n 个询问,每次求有多少个数对 (x, y),满足 a <= x <= b, c <= y <= d,且gcd(x, y) = k,gcd(x, y) 函数为 x 和 y 的最大公约数。1 <= n <= 50000, 1 <= a <= b <=50000, 1 <= c <= d <= 50000, 1 <= k <= 50000

思路:
首先利用容斥原理将一个询问拆分成四个,每次询问有多少个数对(x,y)满足1<=x<=n,1<=y<=m且gcd(x,y)=k,这个问题等价于询问有多少个数对(x,y)满足1<=x<=floor(n/k),1<=y<=floor(m/k)且x与y互质。
由于之前的结论,我们可以令f(i)为1<=x<=n,1<=y<=m且gcd(x,y)=i的数对(x,y)的个数,F(i)为1<=x<=n,1<=y<=m且gcd(x,y)为i的倍数的数对(x,y)的个数
那么显然 F ( i ) = ⌊ n i ⌋ ⌊ m i ⌋ F(i) = \lfloor \frac{n}{i} \rfloor \lfloor \frac{m}{i} \rfloor F(i)=inim
代入到莫比乌斯反演中,得到 f ( i ) = ∑ i ∣ d u ( d i ) F ( d ) = ∑ i ∣ d u ( d i ) ⌊ n d ⌋ ⌊ m d ⌋ f(i) = \sum_{i|d}u(\frac{d}{i})F(d) = \sum_{i|d}u(\frac{d}{i})\lfloor \frac{n}{d} \rfloor \lfloor \frac{m}{d} \rfloor f(i)=idu(id)F(d)=idu(id)dndm 然后枚举每一个k的倍数即可。
优化: ⌊ n d ⌋ ⌊ m d ⌋ \lfloor \frac{n}{d} \rfloor \lfloor \frac{m}{d} \rfloor dndm都最多有 2 n 和 2 m 2\sqrt{n}和2\sqrt{m} 2n 2m 个值,因此枚举这 2 ( n + m ) 2(\sqrt{n} + \sqrt{m}) 2(n +m )个取值,对莫比乌斯函数维护前缀和,即可在 O ( n ) O(\sqrt{n}) O(n )得出解。

代码来自kuangbin

bool check[N+10];
int prime[N+10];
int mu[N+10];
void Moblus() {
   memset(check,false,sizeof(check));
   mu[1] = 1;
   int tot = 0;
   for(int i = 2; i <= N; i++) {
      if( !check[i] ) {
         prime[tot++] = i;
         mu[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)  {
            mu[i * prime[j]] = 0;
            break;
         } else {
            mu[i * prime[j]] = -mu[i];
         }
      }
   }
}
int sum[N+10];
//找 [1,n],[1,m] 内互质的数的对数
long long solve(int n,int m){
   long long ans = 0;
   if(n > m) swap(n,m);
   for(int i = 1, la = 0; i <= n; i = la+1) {
      la = min(n/(n/i),m/(m/i));
      ans += (long long)(sum[la] - sum[i-1])*(n/i)*(m/i);
   }
   return ans;
}
int main() {
   Moblus();
   sum[0] = 0;
   for(int i = 1;i <= N;i++)
      sum[i] = sum[i-1] + mu[i];
   int a,b,c,d,k;
   int T;
   scanf("%d",&T);
   while(T--){
      scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
      long long ans = solve(b/k,d/k) - solve((a-1)/k,d/k) - solve(b/k,(c-1)/k) + solve((a-1)/k,(c-1)/k);
      printf("%lld\n",ans);
   }
   return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值