莫比乌斯反演总结

ops/2024/11/9 17:08:39/

目录

  • 前置知识
    • 1.1 线性筛 (欧拉筛)
    • 1.2 整除分块 (数论分块)
      • 引理 1
      • 引理 2
      • 引理 3
      • 实现
      • 例 1
      • 例 2
      • 例 3
      • 例 4
    • 1.3 数学知识
      • 积性函数
      • 莫比乌斯函数
      • 狄利克雷(Dirichlet)卷积
  • 莫比乌斯反演
    • 2.1 公式
    • 2.2 常用~(唯一)~结论
    • 2.3 例题
      • 例 1
      • 例 2
      • 例 3
      • 例 4
      • 例 5
      • 练习 1
      • 练习 2
      • 练习 3
      • 练习 4

懵逼乌斯反演总结

前置知识

1.1 线性筛 (欧拉筛)

int prime[N] , tot ;
bool is[N] ;
void get_prime( int n )
{is[0] = is[1] = 1 ;for(int i = 2 ; i <= n ; i ++ ) {if( !is[i] ) {prime[++tot] = i ;}for(int j = 1 ; j <= tot && i*prime[j] <= n ; j ++ ) {is[i*prime[j]] = 1 ;if( i%prime[j] == 0 ) {break ;}}}
}

需要注意的是,线性筛有着非常优秀的性质

对于每个数,一定是被其 最小质因子 标记的

换句话说,对于一个数 n = p 1 a 1 p 2 a 2 . . . p k a k n=p_1^{a_1}p_2^{a_2}...p_k^{a_k} n=p1a1p2a2...pkak,它被标记的过程一定是 1 1 1 开始,每次加入当前最大的因子,即 p k p_k pk,然后 p k − 1 p_{k-1} pk1,直到把 p 1 p_1 p1 加完,就标记到了

线性筛可以高效的计算某些数论函数的值,但对于不同的函数可能有不同的处理方式

1.2 整除分块 (数论分块)

考虑计算: ∑ i = 1 n ⌊ n i ⌋ \sum_{i=1}^n \left \lfloor \frac{n}{i} \right \rfloor i=1nin

其中 n ≤ 1 0 12 n\leq10^{12} n1012

研究 ⌊ n i ⌋ \left \lfloor \frac{n}{i} \right \rfloor in 这个函数,首先它随 i i i 增大单调不升;其次,会有很多数值相等的段

在这里插入图片描述

这启发我们:将相同的一段打包计算!

引理 1

∀ a , b , c ∈ Z , ⌊ a b c ⌋ = ⌊ ⌊ a b ⌋ c ⌋ \forall a,b,c\in\mathbb{Z} , \left \lfloor \frac{a}{bc} \right \rfloor=\left \lfloor \frac{\left\lfloor \frac{a}{b}\right\rfloor}{c} \right \rfloor a,b,cZ,bca=cba

在这里插入图片描述
摘自 oi.wiki

引理 2

   ⌊ n i ⌋ \large\left \lfloor \frac{n}{i} \right \rfloor in 的取值种类不会超过 ⌊ 2 n ⌋ \left\lfloor 2\sqrt n \right\rfloor 2n

在这里插入图片描述

这个引理也告诉我们:段数 n \sqrt n n 的结论是 均摊 的结果!

引理 3

对于常数 n n n,使得式子 ⌊ n i ⌋ = ⌊ n j ⌋ \left\lfloor\frac{n}{i}\right\rfloor=\left\lfloor\frac{n}{j}\right\rfloor in=jn 成立且满足 i ≤ j ≤ n i\leq j\leq n ijn 的最大的 j j j ⌊ n ⌊ n i ⌋ ⌋ \large\left\lfloor\frac{n}{\left\lfloor\frac{n}{i}\right\rfloor}\right\rfloor inn

这个式子告诉我们如何寻找左端点为 l l l 的段的右端点

实现

数论分块可以在 O ( n ) O(\sqrt n) O(n ) 的复杂度内解决形如

∑ i = 1 n ⌊ n i ⌋ f ( i ) \sum_{i=1}^n\left\lfloor\frac{n}{i}\right\rfloor f(i) i=1ninf(i) 的求和式

需要能够快速得到 f f f 在某一段区间的 s u m sum sum

要么是预处理前缀和,要么可以借助数学知识直接得到式子

基本模板:

	int l = 1 , r ;while( l <= n ) {r = n/(n/l) ;// 找到右端点// 对 i:[l,r], 这个取整式是一个定值ans -= 1LL*(K/l)*calc(l,r) ;l = r+1 ; }

例 1

求: ∑ i = 1 k ⌊ n i ⌋ ⌊ m i ⌋ \sum_{i=1}^k\left\lfloor\frac{n}{i}\right\rfloor\left\lfloor\frac{m}{i}\right\rfloor i=1kinim

二维数论分块,为了保证同一段内取值的一定性, r r r 应该取较小的那个转折点

	k = min(n,m) ;int l = 1 , r ;while( l <= k ) {r = min( n/(n/l) , m/(m/l) ) ;ans += 1LL*(n/l)*(m/l)*calc(l,r) ;l = r+1 ; }

在这里插入图片描述

d d d 维数论分块的复杂度为 O ( d n ) O(d\sqrt n) O(dn )

例 2

上取整数论分块

注意到 ⌈ n i ⌉ = ⌊ n − 1 i ⌋ + 1 \left \lceil \frac{n}{i} \right \rceil=\left\lfloor\frac{n-1}{i}\right\rfloor+1 in=in1+1

所以 n n n 的上取整分块等价于 n − 1 n-1 n1 的下取整分块

需要注意分母不为 0 0 0

例 3

CF1780E

好难的题

一句话题意:对于 x , y ∈ [ l , r ] x,y\in[l,r] x,y[l,r],求 g c d ( x , y ) gcd(x,y) gcd(x,y) 的种类数

l ≤ 1 0 9 , r ≤ 1 0 18 l\leq 10^9,r\leq10^{18} l109,r1018

考虑每个 g c d gcd gcd 能否出现

能想到的是对于 每个 d d d 可以找到区间 [ l , r ] [l,r] [l,r] 中所有它的倍数,然后没法了,不知道怎么恰好取到 d d d

但我们会发现 : g c d ( k d , ( k + 1 ) d ) = d gcd(kd,(k+1)d)=d gcd(kd,(k+1)d)=d ,也就是说 [ l , r ] [l,r] [l,r]只要有两个及以上 d d d 的倍数,那么任取相邻的两个就行

分析一下,当 l ≤ d ≤ r l\leq d\leq r ldr 时, d d d 本身就在区间中出现一次了,那么只需 2 × d ≤ r 2\times d\leq r 2×dr 即可,这部分可以 O ( 1 ) O(1) O(1)

接下来,就是要求 ∑ d = 1 l [ ⌈ l d ⌉ < ⌊ r d ⌋ ] \sum_{d=1}^l[\left \lceil \frac{l}{d} \right \rceil < \left\lfloor \frac{r}{d}\right\rfloor] d=1l[dl<dr]

枚举 d d d 复杂度还是不行,我们数论分块

一个朴素想法是同时对 l , r l,r l,r 分块,但对 r r r 分块的复杂度是 O ( 1 0 18 ) O(\sqrt {10^{18}}) O(1018 ),寄

那么只能对 l l l 分块了,确定了 ⌈ l d ⌉ \large\left \lceil \frac{l}{d} \right \rceil dl 的值后,合法的 r r r 就成了一段区间,可以 O ( 1 ) O(1) O(1) 算范围

复杂度 O ( l ) O(\sqrt l) O(l )

int T ;
LL l , r , ans ;
void solve()
{// d>=lans = max((r/2)-l+1,0LL) ;// d < lif( l > 1 ) { // 不能让分母为 0LL L = 1 , R = 0 ;while( L < l ) {R = (l-1)/((l-1)/L) ;LL x = (l-1)/L+1+1 , rr = r/x ;rr = max(0LL,rr-2) ;while( x<=r/(rr+1) ) rr++ ;//这两行是抹平微小的误差rr = min(rr,R) ;ans += max(0LL,rr-L+1) ;L = R+1 ;}}printf("%lld\n" , ans ) ;
}

例 4

[清华集训2012] 模积和

一个小学生都知道的结论: n m o d i = n − ⌊ n i ⌋ i n\mod i=n-\left\lfloor\frac{n}{i}\right\rfloor i nmodi=nini

然后就是化化式子


1.3 数学知识

积性函数

定义:若 ∀ x , y \forall x,y x,y 满足 g c d ( x , y ) = 1 gcd(x,y)=1 gcd(x,y)=1,都有 f ( x y ) = f ( x ) × f ( y ) f(xy)=f(x)\times f(y) f(xy)=f(x)×f(y),则 f f f 为积性函数

特别的,若不需要 x , y x,y x,y 互质的条件, ∀ x , y \forall x,y x,y 都有 f ( x y ) = f ( x ) f ( y ) f(xy)=f(x)f(y) f(xy)=f(x)f(y),称 f f f 为完全积性函数

常见的积性函数:

  • 单位函数 e ( n ) = [ n = 1 ] e(n)=[n=1] e(n)=[n=1] ,完全积性
  • 幂函数 I d k ( n ) = n k \mathrm{Id}_k(n)=n^k Idk(n)=nk I d 1 \mathrm{Id}_1 Id1 通常简记为 i d id id,完全积性
  • 常数函数 1 ( n ) = 1 1(n)=1 1(n)=1,完全积性
  • 约数函数 σ k ( n ) = ∑ d ∣ n d k \sigma_k(n)=\sum_{d|n}d^k σk(n)=dndk ,积性
    特别的, k = 0 k=0 k=0 时为约数个数函数,可记为 d ( n ) d(n) d(n) k = 1 k=1 k=1 时为约数和函数,记为 σ ( n ) \sigma(n) σ(n)
  • 欧拉函数 φ ( n ) = ∑ i = 1 n [ g c d ( n , i ) = 1 ] \varphi(n)=\sum_{i=1}^n[gcd(n,i)=1] φ(n)=i=1n[gcd(n,i)=1],积性
  • 莫比乌斯函数 μ ( n ) = { 1 n = 1 0 n 含有平方因子 ( − 1 ) k k 为 n 的不同质因子个数 } \mu(n)=\begin{Bmatrix} 1& n=1 \\ 0& n含有平方因子\\ (-1)^k& k为n的不同质因子个数 \end{Bmatrix} μ(n)= 10(1)kn=1n含有平方因子kn的不同质因子个数 ,积性

莫比乌斯函数

μ ( n ) = { 1 n = 1 0 n 含有平方因子 ( − 1 ) k k 为 n 的不同质因子个数 } \mu(n)=\begin{Bmatrix} 1& n=1 \\ 0& n含有平方因子\\ (-1)^k& k为n的不同质因子个数 \end{Bmatrix} μ(n)= 10(1)kn=1n含有平方因子kn的不同质因子个数

形式很奇怪,但实际上它反映了一种 对每个约数考虑的容斥系数

第二条说人话就是:若存在某个质数 p p p n n n 的质因子分解中 p p p 的指数 ≥ 2 \geq 2 2,则 μ ( n ) = 0 \mu(n)=0 μ(n)=0

性质

∑ d ∣ n μ ( d ) = [ n = 1 ] \sum_{d|n}\mu(d)=[n=1] dnμ(d)=[n=1]

证明:

n = p 1 a 1 . . . p k a k n=p_1^{a_1}...\ p_k^{a_k} n=p1a1... pkak

显然当 d d d 取到的某个质因子指数 ≥ 2 \geq 2 2 是没有贡献的,只需考虑 0 , 1 0,1 0,1 的情况

k k k 个质因子中取 i i i 个指数为 1 1 1,那么原和式即为: ∑ i = 0 k C k i ( − 1 ) i = ( 1 − 1 ) k = [ k = 0 ] \sum_{i=0}^kC_k^i(-1)^i=(1-1)^k=[k=0] i=0kCki(1)i=(11)k=[k=0]

( 最后一步相信你是理解的

[ n = 1 ] [n=1] [n=1],证毕

求法

积性函数,直接线性筛,好写

int mu[N] , prime[N] , tot ;
bool is[N] ;
void get_Mu( int n )
{is[0] = is[1] = 1 ; mu[1] = 1 ;for(int i = 2 ; i <= n ; i ++ ) {if( !is[i] ) {prime[++tot] = i ;mu[i] = -1 ;}for(int j = 1 ; j <= tot && prime[j]*i <= n ; j ++ ) {is[i*prime[j]] = 1 ;if( i%prime[j] == 0 ) {mu[i*prime[j]] = 0 ;//已经加过这个因子了break ;}else mu[i*prime[j]] = -mu[i] ;//换了一种因子加}}
}

狄利克雷(Dirichlet)卷积

定义两个数论函数 f , g f,g f,g 的狄利克雷卷积为 ( f ∗ g ) ( n ) = ∑ d ∣ n f ( d ) g ( n d ) (f*g)(n)=\sum_{d|n}f(d)g(\frac{n}{d}) (fg)(n)=dnf(d)g(dn) 简单点说就是你一半,我一半,再求和

性质

  1. 满足交换律、结合律、分配律

  2. f , g f,g f,g 为积性函数, f ∗ g f*g fg 也为积性函数 (快速判断一个函数好不好筛)

  3. e e e 为狄利克雷卷积的单位元,即 ( f ∗ e ) ( n ) = f ( n ) (f*e)(n)=f(n) (fe)(n)=f(n)

    e = μ ∗ 1 = ∑ d ∣ n μ ( d ) e=\mu*1=\sum_{d|n}\mu(d) e=μ1=dnμ(d)

    证明: ( f ∗ e ) ( n ) = ∑ d ∣ n f ( d ) e ( n d ) = ∑ d ∣ n f ( d ) ∑ k ∣ n d μ ( k ) = ∑ d ∣ n f ( d ) [ n d = 1 ] (f*e)(n)=\sum_{d|n}f(d)e(\frac{n}{d})=\sum_{d|n}f(d)\sum_{k|\frac{n}{d}}\mu(k)=\sum_{d|n}f(d)[\frac{n}{d}=1] (fe)(n)=dnf(d)e(dn)=dnf(d)kdnμ(k)=dnf(d)[dn=1]

    最后一步用了 μ \mu μ 函数的性质

    显然只有当 n = d n=d n=d 时才有贡献,贡献为 f ( n ) f(n) f(n)

    所以 e = μ ∗ 1 e=\mu *1 e=μ1 满足单位元的性质

一些神奇的结论

  • I d k ∗ 1 = σ k \mathrm{Id_k}*1=\sigma_k Idk1=σk

  • φ ∗ 1 = i d \varphi*1=id φ1=id
    更常见的形式是 n = ∑ d ∣ n φ ( d ) n=\sum_{d|n}\varphi(d) n=dnφ(d)

    相信聪明的你一定会证明的 (利用积性函数的性质)

  • φ = I d ∗ μ \varphi=\mathrm{Id}*\mu φ=Idμ ,学过的两个函数就神奇地建立了联系!

计算

( f ∗ g ) ( n ) = ∑ d ∣ n f ( d ) g ( n d ) (f*g)(n)=\sum_{d|n}f(d)g(\frac{n}{d}) (fg)(n)=dnf(d)g(dn)

  • 求单个函数值: O ( n ) O(\sqrt n) O(n ) 暴力枚举因子
  • [ 1 ∼ n ] [1\sim n] [1n] 所有函数值:
    1. 暴力卷积,枚举 d d d,枚举倍数,复杂度 O ( n l o g n ) O(n\mathrm{log\ n}) O(nlog n) ,忽略了计算 f , g f,g f,g 的复杂度
    2. 有些时候的 “卷积” 是只和质因子有关的,Dirichlet 前缀和可以做到 O ( n l o g l o g n ) O(n\mathrm{log logn)} O(nloglogn)
    3. 更常见的,发现这个函数的某些性质,用线性筛筛出所有函数值,复杂度 O ( n ) O(n) O(n)


莫比乌斯反演

2.1 公式

f , g f,g f,g 为两个数论函数

如果有 f ( n ) = ∑ d ∣ n g ( d ) f(n)=\sum_{d|n}g(d) f(n)=dng(d) 那么 g ( n ) = ∑ d ∣ n f ( d ) μ ( n d ) g(n)=\sum_{d|n}f(d)\mu(\frac{n}{d}) g(n)=dnf(d)μ(dn)

学会了狄利克雷卷积后,证明就变得十分简单

1 1 1 式等价于: f = g ∗ 1 f=g*1 f=g1

2 2 2 式等价于: g = f ∗ μ g=f*\mu g=fμ

只需要 2 2 2 式两边同时卷上一个 1 1 1 即证

2.2 常用(唯一)结论

[ g c d ( i , j ) = 1 ] = ∑ k ∣ i , k ∣ j μ ( k ) [gcd(i,j)=1]=\sum_{k|i,k|j}\mu(k) [gcd(i,j)=1]=ki,kjμ(k)

拆开即可证明

2.3 例题

例 1

求全由小写字母组成、长度为 n n n 的周期性字符串的个数

周期性字符串的定义是 可以由至少一个子串重复大于等于两次得到的字符串

n ≤ 1 0 6 n\leq10^6 n106

f ( n ) f(n) f(n) 表示长度为 n n n 的所有串, g ( n ) g(n) g(n) 表示长度为 n n n,不具有周期的串

f ( n ) = ∑ d ∣ n g ( d ) f(n)=\sum_{d|n}g(d) f(n)=dng(d) ,反演得 g ( n ) = ∑ d ∣ n f ( d ) μ ( n d ) g(n)=\sum_{d|n}f(d)\mu(\frac{n}{d}) g(n)=dnf(d)μ(dn)

f f f 的求法是显然的,那么最终答案 f ( n ) − g ( n ) f(n)-g(n) f(n)g(n)

感觉是不太符合直觉,但很优秀的做法

例 2

求: ∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) = 1 ] \sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=1] i=1nj=1m[gcd(i,j)=1] ,互质数对的个数

n , m ≤ 1 0 12 n,m\leq10^{12} n,m1012

直接套用结论

= ∑ i = 1 n ∑ j = 1 m ∑ k ∣ i , k ∣ j μ ( k ) =\sum_{i=1}^n \sum_{j=1}^m \sum_{k|i,k|j}\mu(k) =i=1nj=1mki,kjμ(k)

考虑每个 μ ( k ) \mu(k) μ(k) 会贡献几次

= ∑ k = 1 m μ ( k ) ∑ i = 1 [ n / k ] ∑ j = 1 [ m / k ] 1 =\sum_{k=1}^m\mu(k)\sum_{i=1}^{[n/k]}\sum_{j=1}^{[m/k]}1 =k=1mμ(k)i=1[n/k]j=1[m/k]1

= ∑ k = 1 m μ ( k ) ⌊ n k ⌋ ⌊ m k ⌋ =\sum_{k=1}^m\mu(k) \left\lfloor\frac{n}{k}\right\rfloor \left\lfloor\frac{m}{k}\right\rfloor =k=1mμ(k)knkm

直接数论分块

例 3

∑ i = 1 n ∑ j = 1 m i j [ g c d ( i , j ) = k ] \sum_{i=1}^n \sum_{j=1}^m ij[gcd(i,j)=k] i=1nj=1mij[gcd(i,j)=k]

n , m , k ≤ 1 0 12 n,m,k\leq 10^{12} n,m,k1012 ,对质数取模

与上一题有两点不同:带系数、不是互质;

既然 g c d gcd gcd k k k,我们不妨直接枚举 i k , j k ik,jk ik,jk

= ∑ i = 1 [ n / k ] ∑ j = 1 [ m / k ] i j k 2 [ g c d ( i , j ) = 1 ] =\sum_{i=1}^{[n/k]}\sum_{j=1}^{[m/k]}ijk^2[gcd(i,j)=1] =i=1[n/k]j=1[m/k]ijk2[gcd(i,j)=1]

成功转化成 互质数对,带结论

= ∑ i = 1 [ n / k ] ∑ j = 1 [ m / k ] i j k 2 ∑ d ∣ i , d ∣ j μ ( d ) =\sum_{i=1}^{[n/k]}\sum_{j=1}^{[m/k]}ijk^2\sum_{d|i,d|j}\mu(d) =i=1[n/k]j=1[m/k]ijk2di,djμ(d)

= ∑ d = 1 m μ ( d ) k 2 ∑ i = 1 [ n / k / d ] i d ∑ j = 1 [ m / k / d ] j d =\sum_{d=1}^{m}\mu(d)k^2\sum_{i=1}^{[n/k/d]}id\sum_{j=1}^{[m/k/d]}jd =d=1mμ(d)k2i=1[n/k/d]idj=1[m/k/d]jd

= k 2 × ∑ d = 1 m μ ( d ) d 2 × ∑ i = 1 [ n / k / d ] i ∑ j = 1 [ m / k / d ] j =k^2 \times \sum_{d=1}^{m}\mu(d)d^2 \times \sum_{i=1}^{[n/k/d]}i\sum_{j=1}^{[m/k/d]}j =k2×d=1mμ(d)d2×i=1[n/k/d]ij=1[m/k/d]j

后两项就是等差数列了,对 ⌊ n k d ⌋ \left\lfloor \frac{n}{kd} \right\rfloor kdn ⌊ m k d ⌋ \left\lfloor \frac{m}{kd} \right\rfloor kdm 数论分块即可做到 O ( n ) O(\sqrt n) O(n )

例 4

∑ i = 1 n ∑ j = 1 m l c m ( i , j ) \sum_{i=1}^{n} \sum_{j=1}^{m}lcm(i,j) i=1nj=1mlcm(i,j)

多次询问, T ≤ 1 0 3 , n , m ≤ 1 0 7 T\leq 10^3,\ n,m\leq10^7 T103, n,m107

首先可以转化成 g c d gcd gcd 的形式

= ∑ i = 1 n ∑ j = 1 m i j g c d ( i , j ) =\sum_{i=1}^{n} \sum_{j=1}^{m}\frac{ij}{\mathrm{gcd}(i,j)} =i=1nj=1mgcd(i,j)ij

同样的考虑每个 g c d \mathrm{gcd} gcd 的贡献

= ∑ i = 1 n ∑ j = 1 m ∑ d = 1 m i j d [ g c d ( i , j ) = d ] =\sum_{i=1}^{n} \sum_{j=1}^{m} \sum_{d=1}^{m} \frac{ij}{d}\ [\mathrm{gcd}(i,j)=d] =i=1nj=1md=1mdij [gcd(i,j)=d]

= ∑ d = 1 m 1 d × ∑ i = 1 n ∑ j = 1 m i j [ g c d ( i , j ) = d ] =\sum_{d=1}^{m} \frac{1}{d} \times \sum_{i=1}^{n} \sum_{j=1}^{m} ij\ [\mathrm{gcd}(i,j)=d] =d=1md1×i=1nj=1mij [gcd(i,j)=d]

= ∑ d = 1 m 1 d × ∑ i = 1 [ n / d ] ∑ j = 1 [ m / d ] i j d 2 [ g c d ( i , j ) = 1 ] =\sum_{d=1}^{m} \frac{1}{d} \times \sum_{i=1}^{[n/d]} \sum_{j=1}^{[m/d]} ijd^2\ [\mathrm{gcd}(i,j)=1] =d=1md1×i=1[n/d]j=1[m/d]ijd2 [gcd(i,j)=1]

= ∑ d = 1 m d × ∑ i = 1 [ n / d ] ∑ j = 1 [ m / d ] i j ∑ k ∣ i , k ∣ j μ ( k ) =\sum_{d=1}^{m} d \times \sum_{i=1}^{[n/d]} \sum_{j=1}^{[m/d]} ij \sum_{k|i,k|j}\mu(k) =d=1md×i=1[n/d]j=1[m/d]ijki,kjμ(k)

= ∑ d = 1 m d ∑ k = 1 [ m / d ] μ ( k ) × ∑ i = 1 [ n / k d ] ∑ j = 1 [ m / k d ] i k × j k =\sum_{d=1}^{m} d \sum_{k=1}^{[m/d]}\mu(k)\times \sum_{i=1}^{[n/kd]} \sum_{j=1}^{[m/kd]} ik\times jk =d=1mdk=1[m/d]μ(k)×i=1[n/kd]j=1[m/kd]ik×jk

= ∑ d = 1 m d ∑ k = 1 [ m / d ] μ ( k ) k 2 × ∑ i = 1 [ n / k d ] ∑ j = 1 [ m / k d ] i j =\sum_{d=1}^{m} d \sum_{k=1}^{[m/d]}\mu(k) k^2 \times \sum_{i=1}^{[n/kd]} \sum_{j=1}^{[m/kd]} ij =d=1mdk=1[m/d]μ(k)k2×i=1[n/kd]j=1[m/kd]ij

以上用到的技巧都与前面的例题相同,相信你一定可以独立完成的

与之前不同的是,这里最外层的 d d d 不是定值,需要枚举,使得复杂度增高

朴素的想法是,对于外层 d d d 的枚举 按 ⌊ n d ⌋ \left\lfloor \frac{n}{d} \right\rfloor dn ⌊ m d ⌋ \left\lfloor \frac{m}{d} \right\rfloor dm 进行数论分块,这样每段内后面的式子是个定值

要计算后面的式子,可以再对 k k k 的枚举进行分块,与 例 3 一致

然而这样复杂度是 O ( n × n ) = O ( n ) O(\sqrt n \times \sqrt n)=O(n) O(n ×n )=O(n) (网上都这么说,但实际打表发现比 n n n 小得多,但题目要卡这种做法的话还是过不了的)

一个优雅且很常用的技巧:更改枚举变量

枚举 d , k d,k d,k 后,需要 d × k d\times k d×k 的值,我们考虑直接枚举乘积

T = k d T=kd T=kd ,则 d ∣ T d|T dT

= ∑ T = 1 m ∑ i = 1 [ n / T ] i ∑ j = 1 [ m / T ] j × ∑ d ∣ T d × ( T d ) 2 μ ( T d ) =\sum_{T=1}^{m} \sum_{i=1}^{[n/T]}i \sum_{j=1}^{[m/T]}j \times \sum_{d|T}d\times (\frac{T}{d})^2\mu(\frac{T}{d}) =T=1mi=1[n/T]ij=1[m/T]j×dTd×(dT)2μ(dT)

= ∑ T = 1 m ∑ i = 1 [ n / T ] i ∑ j = 1 [ m / T ] j × ∑ d ∣ T T d μ ( T d ) T =\sum_{T=1}^{m} \sum_{i=1}^{[n/T]}i \sum_{j=1}^{[m/T]}j \times \sum_{d|T}\frac{T}{d}\mu(\frac{T}{d})T =T=1mi=1[n/T]ij=1[m/T]j×dTdTμ(dT)T

注意后面的式子,设 f ( T ) = ∑ d ∣ T μ ( d ) d T f(T)=\sum_{d|T}\mu(d)d\ T f(T)=dTμ(d)d T

先不管 T T T f ( T ) = ∑ d ∣ T μ ( d ) d f(T)=\sum_{d|T}\mu(d)d f(T)=dTμ(d)d

发现这个东西并不是一个卷积。。。

但这个显然也可以暴力 n l o g n n\mathrm{logn} nlogn 求,但是不行

分析一下性质,设 a , b a,b a,b 互质

F ( a b ) , F ( a ) × F ( b ) F(ab),F(a)\times F(b) F(ab),F(a)×F(b) 会相等吗?

分析一下,计算 F ( a b ) F(ab) F(ab) 时,枚举一个它的因子 d d d ,考虑 d d d 必定可以拆分到 a , b a,b a,b 两个数里,设为 d a , d b d_a,d_b da,db

那么在 F ( a b ) F(ab) F(ab) 中有贡献 d × μ ( d ) d\times \mu(d) d×μ(d),在 F ( a ) F(a) F(a) d a μ ( d a ) d_a\mu (d_a) daμ(da),在 F ( b ) F(b) F(b) d b μ ( d b ) d_b\mu(d_b) dbμ(db),后两者乘起来显然等于前者

这样显然是双射关系,那么贡献完全一样, F ( a b ) = F ( a ) × F ( b ) F(ab)=F(a)\times F(b) F(ab)=F(a)×F(b)

积性函数,我们就可以大胆筛了,筛一个函数一般需要考虑这几种转移:

F ( 1 ) = 1 F(1)=1 F(1)=1

F ( p ) = 1 − p F(p)=1-p F(p)=1p p p p 为质数

i m o d n ≠ 0 i \ \mathrm{mod\ n}≠0 i mod n=0 时, F ( i × p ) = F ( i ) × F ( p ) F(i\times p)=F(i)\times F(p) F(i×p)=F(i)×F(p),直接套用积性函数的性质即可

i m o d n = 0 i \ \mathrm{mod\ n}=0 i mod n=0 时 (一般来说这是唯一的难点),这个需要分析一下:

若枚举 i p ip ip 的因子 d d d 本来就是 i i i 的因子,这一部分总贡献就是 F ( i ) F(i) F(i) ;

反之,枚举的 d d d 不是 i i i 的因子,也就是 d d d 质因子分解后 p p p 的指数为 i i i p p p 的指数加 1 1 1

这不就说明,此时 d d d p p p 的指数 ≥ 2 \geq 2 2 吗?

所以这部分贡献为 0 0 0

综上,当 i m o d n = 0 i \ \mathrm{mod\ n}=0 i mod n=0 时, F ( i × p ) = F ( i ) F(i\times p)=F(i) F(i×p)=F(i)

然后就可以直接筛了,预处理一次 O ( n ) O(n) O(n),多次询问,每次只需要一个数论分块,复杂度 O ( T n ) O(T\sqrt n) O(Tn )

#include<bits/stdc++.h>
using namespace std ;typedef long long LL ;
const int N = 1e7+10 , mod = 1e8+9 ;
// 需要分块套分块时,考虑枚举第二个块中的某些东西
// 写成更朴素的求和形式,猜积性函数的性质 int n , m ;
int prime[N] , tot ;
LL S[N] , F[N] ;
bool is[N] ;
void get_Mu( int n )
{is[0] = is[1] = 1 ; F[1] = S[1] = 1 ;for(int i = 2 ; i <= n ; i ++ ) {if( !is[i] ) {prime[++tot] = i ;F[i] = 1-i ;}for(int j = 1 ; j <= tot && prime[j]*i <= n ; j ++ ) {is[i*prime[j]] = 1 ;if( i%prime[j] == 0 ) {F[i*prime[j]] = F[i] ;break ;}else F[i*prime[j]] = F[i]*F[prime[j]]%mod ;}S[i] = ( S[i-1] + F[i]*i ) % mod ;}
}
inline LL V ( int x )
{return 1LL*x*(x+1)/2%mod ;
}int main()
{int T ;scanf("%d" , &T ) ;get_Mu(1e7) ;while( T -- ) {scanf("%d%d" , &n , &m ) ;if( n < m ) swap(n,m) ;LL ans = 0 ;int l = 1 , r = 0 ;while( l <= m ) {r = min( n/(n/l) , m/(m/l) ) ;// T:[l,r]ans = ( ans + (S[r]-S[l-1])*V(n/l)%mod*V(m/l) ) % mod ; l = r+1 ;}printf("%lld\n" , (ans+mod)%mod ) ;}return 0 ;
}

这个技巧是非常非常非常常用的:多测时,更改枚举变量 + 构造与 n , m n,m n,m 无关的函数 + 推性质线性筛

例 5

[SDOI2015] 约数个数和

本题需要一个结论:

d ( i × j ) = ∑ x ∣ i ∑ y ∣ j [ g c d ( x , y ) = 1 ] d(i\times j)=\sum\limits_{x|i}\sum\limits_{y|j}[gcd(x,y)=1] d(i×j)=xiyj[gcd(x,y)=1]

一句话:两数乘积的约数个数,等于两数约数中的互质对个数

简单证明:

依次考虑每种质因子对答案的贡献

对于左边,小学生都知道的公式是 d ( n ) = ( a 1 + 1 ) ( a 2 + 2 ) . . . d(n)=(a_1+1)(a_2+2)... d(n)=(a1+1)(a2+2)... a i a_i ai 是将 n n n 质因子分解后 p i p_i pi 的指数

考虑质数 p k p_k pk ,设在 i i i 中有 a i a_i ai 个, j j j 中有 a j a_j aj 个,贡献系数就是 a i + a j + 1 a_i+a_j+1 ai+aj+1

对于右边,虽然是求和式,但每个质因子带来的贡献其实是乘上某个值

还是考虑 p k p_k pk,那么 x x x y y y p k p_k pk 的指数不能同时不为 0 0 0

在这个限制下,这一种质因子的方案显然是 a i + 1 + a j + 1 − 1 = a i + a j + 1 a_i+1+a_j+1-1=a_i+a_j+1 ai+1+aj+11=ai+aj+1 − 1 -1 1 是减掉两个都选 0 0 0 的情况,算了两次

那么左右两边就相等了

接下来的推式子,相信聪明的你一定可以完成的!

练习 1

YY的GCD

与例 4 一致,对于最后处理出来的函数直接筛

然鹅由于这个函数就是只与质数相关的,可以 Dirichlet 前缀和

练习 2

于神之怒加强版

本题数据范围不大,可以直接暴力卷积,但我们考虑怎么筛

显然 k = 1 k=1 k=1 时就是欧拉反演 (从某佬的blog中听来的名称)

k ≥ 2 k\geq 2 k2,无法直接想明白时打表也是很不错的选择哦!

练习 3

[SDOI2014] 数表

a a a 的限制,最终是个分段函数,每次询问不得不重新筛?

继承暴力卷积的思想,考虑每个因子的贡献

由此想到将询问离线,动态删除某个因子对其所有倍数的贡献,然后查区间和

直接树状数组可以做到 O ( Q n l o g n + Q l o g 2 n ) O(Q\sqrt n\mathrm{logn}+Q\mathrm{log^2n}) O(Qn logn+Qlog2n)

更优秀的做法是用分块平衡一下复杂度,最终可以达到 O ( Q n l o g n ) O(Q\sqrt {n\mathrm{logn}}) O(Qnlogn )

练习 4

在这里插入图片描述
好题,一定要再看


http://www.ppmy.cn/ops/104136.html

相关文章

汽车免拆诊断案例 | 马自达CX-3无音频输出

故障现象&#xff1a; 使用触摸屏打开收音机时&#xff0c;单选按钮打开收音机&#xff0c;但无法访问菜单。使用中控台中的旋转控制旋钮时&#xff0c;也会遇到相同的情况。 没有音频输出到车上的任何扬声器&#xff0c;包括卫星导航、蓝牙或语音识别。音量调节也不起作用&a…

word宏代码选择所有公式 选择所有表格

选择视图-宏代码 输入宏名字【SelectAllEquations】&#xff0c;选择加号&#xff0c;添加宏代码 输入宏代码&#xff0c;并保存&#xff0c;然后关闭&#xff1a; Sub SelectAllEquations()Dim xMath As OMathDim I As IntegerWith ActiveDocument.DeleteAllEditableRanges w…

【提示学习论文】CoCoLe:Conceptual Codebook Learning for Vision-Language Models

Conceptual Codebook Learning for Vision-Language Models&#xff08;ECCV 2024&#xff09; CPL的改进暂无代码 CPL 详见CPL论文 CoCoLe a&#xff1a;手工概念缓存的建立过程b&#xff1a;制作提示的过程&#xff0c;将图像输入Ev&#xff0c;得到image features v 作…

一个比 Nginx 还简单的 Web 服务器

企业级的 Web 服务器非常多&#xff0c;Nginx、Tomcat、Apache、IIS、FastAPI、Flask 等。今天松哥再给大家介绍一个开源的 Web 服务器&#xff0c;这款服务器具备自动 HTTPS 功能和高度可配置性&#xff0c;它的名字是&#xff1a;Caddy。 Caddy 是一个 Go 编写的 Web 服务器&…

基于SSM+小程序的宿舍管理系统(宿舍1)(源码+sql脚本+视频导入教程+文档)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 本宿舍管理系统小程序有管理员和学生两个角色。 1、管理员功能有个人中心&#xff0c;公告信息管理&#xff0c;班级管理&#xff0c;学生管理&#xff0c;宿舍信息管理&#xff0c;宿舍…

基于STM32的无线语音放大系统设计

本设计基于STM32设计了一种无线语音放大系统。该系统由语音采集模块、STM32核心控制模块、NRF24L01无线通信模块和语音放大模块组成。语音采集模块承担着对采集到的语音信号进行预处理的任务。STM32单片机负责控制整个系统的运行过程&#xff0c;包括数据处理、发送端的模数转换…

基于单片机的家居环境监测系统的设计

本设计基于单片机的家居环境监测系统&#xff0c;采用STM32F103C6T6单片机作为主要的控制芯片&#xff0c;环境监测方面采用SHT30模块实现室内温度和湿度的监测&#xff1b;有害气体监测方面&#xff0c;用MQ-7传感器实现室内一氧化碳气体的监测&#xff1b;采用WIFI模块连接指…

如何打造Java SpringBoot宿舍设备管理系统,全程跟踪设备使用周期,2025最新设计指南

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…