提供另一种推式子的方法。
如同其他题解解释的那样,求出原根
g 后,问题转化为计算离散对数
Km=1∑Mn=1∑N[m⊥n]loggm!n!(m+n−1)!.
为简化记号,下令
Nd=⌊N/d⌋, Md=⌊M/d⌋.
首先,处理分子:(不妨设
N≤M)
F1(M,N)=m=1∑Mn=1∑N[m⊥n]logg(m+n−1)!=d∑μ(d)m=1∑Mdn=1∑Ndlogg((m+n)d−1)!=d∑μ(d)(s=2∑Nd(s−1)+Nd+1∑MdNd+Md+1∑Md+Nd(Md+Nd+1−s))logg(sd−1)!.
最后一步就是取
s=m+n,然后计算每个
s 分别对应的数对
(m,n) 的数目。再令
G0(S,d)G1(S,d)=s=1∑Slogg(sd−1)!,=s=1∑S(s−1)logg(sd−1)!,
就有
F1(M,N)=d∑μ(d)(G1(Nd,d)+Nd(G0(Md,d)−G0(Nd,d))+(Md+Nd)(G0(Md+Nd,d)−G0(Md,d))−(G1(Md+Nd,d)−G1(Md,d)))=d∑μ(d)((Md+Nd)G0(Md+Nd,d)−MdG0(Md,d)−NdG0(Nd,d))+d∑μ(d)(G1(Md,d)+G1(Nd,d)−G1(Md+Nd,d)).
所以只需要预处理
G0(S,d) 和
G1(S,d),然后计算
S 固定时它们与
μ(d) 的乘积对
d 的前缀和就可以做数论分块了。
然后,处理分母:
F2(M,N)=m=1∑Mn=1∑N[m⊥n](loggm!+loggn!)=d∑μ(d)(Nds=1∑Mdlogg(sd)!+Mds=1∑Ndlogg(sd)!).
为避免预处理更多的二维数列,注意到
s=1∑Mdlog(sd)!=G0(Md,d)+loggMd!+Mdloggd.
因而,只需要额外再处理
μ(d) 和
μ(d)loggd 的前缀和即可。
整理下,就有:
d∑μ(d)(Md+Nd)(G0(Md+Nd,d)−G0(Md,d)−G0(Nd,d))+d∑μ(d)(G1(Md+Nd,d)−G1(Md,d)−G1(Nd,d))+d∑μ(d)(MdloggNd!+NdloggMd!)+d∑μ(d)2MdNdloggd.
虽然形式看起来很整洁,但是跑得并没有更快。仍需要竭尽所能地卡常。