莫比乌斯反演
前置知识-OI Wiki
莫比乌斯函数 (mu)
[mu(n)= egin{cases} 1&n=1\ 0&n ext{ 含有平方因子}\ (-1)^k&k ext{ 为 }n ext{ 的本质不同质因子个数}\ end{cases}
]
当 (x⊥y) ,
如果其中一个有平方因子,(mu(x)*mu(y)=0=mu(xy)) 。
如果两数都不含平方因子,(mu(x)*mu(y)=(-1)^{k_x+k_y}=mu(xy))。
所以 (mu) 是个积性函数。
性质:
[sum_{dmid n}mu(d)= egin{cases} 1&n=1\ 0&n
eq 1\ end{cases}
]
证明:
令 (n=prodlimits_{i=1}^kp_i^{c_i},n'=prodlimits_{i=1}^kp_i) 。
显然有 (sumlimits_{d|n}mu(d)=sumlimits_{d|n'}mu(d)) ,因为枚举平方因子是无意义的。
那么这等价于在 (k) 个数里面选 0 个 即 (mu(1)) ,贡献是 1,选 1 个,贡献是 -1,选 2 个,贡献是 1 ,选 (t) 个,贡献是 ((-1)^t) ,也就是 (sumlimits_{i=0}^kdbinom{k}{i}(-1)^i=(1-1)^k=[k==0])。
当 k=0 时,n=1。
于是就有 ([n==1]\,↔\,sum_{d|n}mu(d)) ,那么罪恶的东西要来了...
我们都知道,莫比乌斯反演最喜欢的就是 gcd,那就可以把 ([gcd(i,j)=1]) 替换为 (sum_{d|gcd(i,j)}mu(d)) 。
那么就可以:
[egin{align}
&sum_{i=1}^nsum_{j=1}^n[gcd(i,j)=1]\
=&sum_{i=1}^nsum_{j=1}^nsum_{d|gcd(i,j)}mu(d)\
=&sum_{d=1}^nsum_{i=1}^nsum_{j=1}^n[d|i][d|j]mu(d)\
=&sum_{d=1}^nmu(d)sum_{i=1}^{lfloorfrac{n}{d}
floor}sum_{j=1}^{lfloorfrac{n}{d}
floor}1\
=&sum_{d=1}^nmu(d)lfloorfrac{n}{d}
floorlfloorfrac{n}{d}
floor
end{align}
]
于是预处理 (mu) ,再每个询问整除分块,就可以做到 (mathcal O(n+Tsqrt{n})) 了。
莫比乌斯反演
真正的反演。
(f(n)=sum_{d|n}g(d)\,↔\,g(n)=sum_{d|n}mu(d)f(frac{n}{d})\)
证明:
[egin{align}
&sum_{d|n}mu(d)f(frac{n}{d})\
=&sum_{d|n}mu(d)sum_{k|frac{n}{d}}g(k)\
=&sum_{k|n}g(k)sum_{d|frac{n}{k}}mu(d)\
=&g(n)
end{align}
]
虽然不会用,但结论就是这样...下面是几道例题。
[button color="success" icon="" url="https://www.luogu.com.cn/problem/P1447" type="round"]P1447[NOI2010] 能量采集[/button]
((n,mleq10^5))
[egin{align}
ans&=sum^n_{i=1}sum^m_{j=1}(2*gcd(i,j)-1)\
&=2*sum^n_{i=1}sum^m_{j=1}gcd(i,j)-n*m\
S&=sum^n_{i=1}sum^m_{j=1}gcd(i,j)\
ans&=2S-n*m
end{align}
]
[egin{align}
f(d)&=sum^n_{i=1}sum^m_{j=1}[gcd(i,j)=d]\
&=sum^{lfloorfrac{n}{d}
floor}_{i=1}sum^{lfloorfrac{m}{d}
floor}_{j=1}[gcd(i,j)=1]\
&=sum_{d'}mu(d')sum_{i=1}^{lfloorfrac{n}{d}
floor}[d'|i]sum_{j=1}^{lfloorfrac{m}{d}
floor}[d'|j]\
&=sum_{d'}mu(d')lfloorfrac{n}{dd'}
floorlfloorfrac{m}{dd'}
floor
end{align}
]
[egin{align}
S&=sum_{d}f(d)*d\
&=sum_{d=1}^nd*sum_{d'=1}^{lfloorfrac{n}{d}
floor}mu(d')lfloorfrac{n}{dd'}
floorlfloorfrac{m}{dd'}
floor\
end{align}\
]
求 (S) 时两段数论分块,可以做到 (O(sqrt{n}*sqrt{n})=O(n)) ,但 (T) 组数据时总时间复杂度达到 (O(n+Tn)),不太优秀。
对于求(sum^n_{i=1}sum^m_{j=1}gcd(i,j)),其实还有另一种更高效的方法。
证明:(sum_{d|n}phi(d)=n)
设 (f(n)=sum_{d|n}phi(d))。
设 (a⊥b) ,则 (phi(a)*phi(b)=phi(ab)),那么
[egin{align}
&f(a)*f(b)\
=&sum_{i|a}phi(i)sum_{j|b}phi(b)\
=&sum_{i|a}sum_{j|b}phi(i)*phi(j)\
=&sum_{i|a}sum_{j|b}phi(i*j)\
=&sum_{d|ab}phi(d)\
=&f(ab)
end{align}
]
即 (f) 也是积性函数,那么
[egin{align}
&f(p^k)\
=&sum_{i=0}^kphi(p^i)\
=&1+(p-1)+(p^2-p)+...+(p^k-p^{k-1})\
=&p^k
end{align}
]
于是设 (n=prod_{i=1}^mp_i^{k_i}),(f(n)=prod_{i=1}^mf(p_i^{k_i})=prod_{i=1}^mp_i^{k_i}=n)。
证毕。
回到求 (sum^n_{i=1}sum^m_{j=1}gcd(i,j)) 身上,把 (gcd(i,j)) 换成 (f(gcd(i,j))) ,那么
[egin{align}
&sum^n_{i=1}sum^m_{j=1}gcd(i,j)\
=&sum^n_{i=1}sum^m_{j=1}sum_{d|gcd(i,j)}phi(d)\
=&sum_dphi(d)sum_{i=1}^n[d|i]sum_{j=1}^m[d|j]\
=&sum_dphi(d)lfloorfrac{n}{d}
floorlfloorfrac{m}{d}
floor
end{align}
]
这样虽然单次询问需要线性筛 (phi) ,时间复杂度 (O(n+sqrt{n})),
但在 (T) 组数据时可以做到 (O(n+Tsqrt{n})),比上面方法的 (O(n+Tn)) 更优。
利用了欧拉函数 (sum_{d|n}phi(d)=n) 的性质,也称这种方法叫欧拉反演。
[button color="success" icon="" url="https://www.luogu.com.cn/problem/P6222" type="round"]P6222 「P6156 简单题」加强版[/button]
(T) 组数据,求
[sum^n_{i=1}sum_{j=1}^n(i+j)^Kmu^2(gcd(i,j))gcd(i,j)
]
((T=10^4,nleq10^7))
[egin{align}
&sum_dmu^2(d)* d*sum_{i=1}^nsum_{j=1}^n(i+j)^K[gcd(i,j)=d]\
=&sum_dmu^2(d)*d*d^K*sum_{i=1}^{lfloorfrac{n}{d}
floor}sum_{j=1}^{lfloorfrac{n}{d}
floor}(i+j)^K[gcd(i,j)=1]\
=&sum_dmu^2(d)*d*d^K*sum_{d'}mu(d')d'^Ksum_{i=1}^{lfloorfrac{n}{dd'}
floor}sum_{j=1}^{lfloorfrac{n}{dd'}
floor}(i+j)^K\
=&sum_TT^Ksum_{d|T}mu^2(d)*mu(frac{T}{d})*d*sum_{i=1}^{lfloorfrac{n}{T}
floor}sum_{j=1}^{lfloorfrac{n}{T}
floor}(i+j)^K\
&设\, S(n)=sum_{i=1}^{n}sum_{j=1}^{n}(i+j)^K\
&显然有\, S_n=sum_{s=2}^n(s-1)*s^K+sum_{s=n+1}^{2n}(2n-s+1)*s^K\
&线性筛预处理完全积性函数quad p_n=n^k\,并记录前缀和,那么就可以线性预处理出S_n\
&设\, f_n=sum_{d|n}mu^2(d)mu(frac{n}{d})*d,是积性函数可以线性筛\
上式=&sum_Tf(T)T^KS(lfloorfrac{n}{T}
floor)\
&f(T)T^K可以做前缀和,后面的整除分块\
&O(n+Tsqrt{n})
end{align}]