做 /tuu 了这题,有被恶心到……真就「一杯茶,一包烟,一(六)道莫反做一天」呗……考场上遇到这种题肯定果断拿个 60pts 跑路……
一开始看成了 (sum) 感觉不可做。(prod) 是可以拆开的(就像加法遇到 (sum) 也可以拆开),设
[a=prod_{i=1}^Aprod_{j=1}^Bprod_{k=1}^Ci^{f(type)}\
b=prod_{i=1}^Aprod_{j=1}^Bprod_{k=1}^Cj^{f(type)}\
c=prod_{i=1}^Aprod_{j=1}^Bprod_{k=1}^Cgcd(i,j)^{f(type)}\
d=prod_{i=1}^Aprod_{j=1}^Bprod_{k=1}^Cgcd(i,k)^{f(type)}
]
那么 (ans=dfrac{ab}{cd})。又注意到 (a,b) 和 (c,d) 这两组是对称的,推柿子的时候每组只需要算一个,实现的时候就把某两个变量调换位置然后 CV 即可。于是任务就是求 (type=0,1,2) 时的 (a,c),一共六个任务。(0a) 和 (1a) 是小学二年级都会的,不需要莫反;(0c) 是究极莫反基础,(1c) 是莫反中等题,想必来挑战这题的人都是会的;这篇题解重点说说 (2a) 和 (2c),感觉有有意思又不失难度(同时还会把人推吐)。
(2a):考虑对 (gcd(i,j,k)) 施加剧本作用:遇到 gcd 直接枚举。
[egin{aligned}
a&=prod_oprod_{i=1}^Ai^{osumlimits_{j=1}^Bsumlimits_{k=1}^C[gcd(i,j,k)=o]}\
&=prod_oprod_{i=1}^{leftlfloorfrac Ao
ight
floor}(io)^{osumlimits_{j=1}^{leftlfloorfrac Bo
ight
floor}sumlimits_{k=1}^{leftlfloorfrac Co
ight
floor}sumlimits_{pmid i,pmid j,pmid k}mu(p)}
end{aligned}
]
把 (prod) 转化成 (sum) 放到指数上反演之后,该放下来更方便地处理了。
[egin{aligned}
a&=prod_oprod_{i=1}^{leftlfloorfrac Ao
ight
floor}prod_{j=1}^{leftlfloorfrac Bo
ight
floor}prod_{k=1}^{leftlfloorfrac Co
ight
floor}prod_{pmid i,pmid j,pmid k}(io)^{omu(p)}\
&=prod_{p}prod_oprod_{i=1}^{leftlfloorfrac A{op}
ight
floor}(iop)^{omu(p)leftlfloorfrac B{op}
ight
floorleftlfloorfrac C{op}
ight
floor}
end{aligned}
]
对 (op) 整除分块。
[egin{aligned}a&=prod_qprod_{pmid q}prod_{i=1}^{leftlfloorfrac Aq
ight
floor}(iq)^{frac qpmu(p)leftlfloorfrac Bq
ight
floorleftlfloorfrac Cq
ight
floor}\
&=prod_qprod_{pmid q}left(leftlfloordfrac Aq
ight
floor!q^{leftlfloorfrac Aq
ight
floor}
ight)^{frac qpmu(p)leftlfloorfrac Bq
ight
floorleftlfloorfrac Cq
ight
floor}
end{aligned}
]
到这儿就有了个做法的雏形:对 (q) 整除分块,然后 (p) 这个 (prod) 就是一个类似狄前的函数在 (q) 处的取值,这里面如果只有 (p,q,dfrac qp) 这三者相关的量的话是可以直接预处理的。但是这里面好死不死有 (A,B,C) 的整除值(在整除分块的时候视作常数,但是对于不同测试点就 GG 了),所以还要继续拆:
[a=prod_qleft(leftlfloordfrac Aq
ight
floor!
ight)^{leftlfloorfrac Bq
ight
floorleftlfloorfrac Cq
ight
floor qsumlimits_{pmid q}frac{mu(p)}p}q^{leftlfloorfrac Aq
ight
floorleftlfloorfrac Bq
ight
floorleftlfloorfrac Cq
ight
floor qsumlimits_{pmid q}frac{mu(p)}p}
]
居然看到了 (sumlimits_{pmid q}dfrac{mu(p)}p) 这个式子,回想起了万年没用过的恒等式 (sumlimits_{imid x}dfrac{mu(i)}i=dfrac{varphi(x)}x)!!!11 于是 (qsumlimits_{pmid q}dfrac{mu(p)}p=varphi(q))。(u1s1 你可能会说这种模意义下拆出分数次幂再化回整数次幂,考虑到高次剩余存在唯一性问题,不太严谨吧?其实大可这样理解:假设全是在复数域下定义的东西,那么这么推显然没毛病,只是题目保证这个式子的值是整数,故最后推出来计算可以取模。所以是完全严谨的)
那么自行替换一下,只需要对 (q) 整除分块,对于一块只要求 (varphi(x)) 的前缀和与 (x^{varphi(x)}) 的前缀积即可,单次询问复杂度 (mathrm O(sqrt nlog n))。
这部分还是不算很难的,只是用到了万年不用的恒等式,感觉很有趣。
(2c):这里面有两个 gcd,是整除关系。zszz 莫反题要谨慎,不能一口气全部反演掉,要一个一个反演然后根据 gcd 之间的关系加限制条件。这个其实先枚举哪个都是能做的,我枚举的是 (gcd(i,j))。
[egin{aligned}c&=prod_oprod_{pmid o}o^{psumlimits_{i=1}^Asumlimits_{j=1}^B[gcd(i,j)=o]sumlimits_{k=1}^C[gcd(k,o)=p]}\
&=prod_oprod_{pmid o}o^{psumlimits_{i=1}^{leftlfloorfrac Ao
ight
floor}sumlimits_{j=1}^{leftlfloorfrac Bo
ight
floor}sumlimits_{qmid i,qmid j}mu(q)sumlimits_{k=1}^{leftlfloorfrac Cp
ight
floor}sumlimits_{rmid k,rmid frac op}mu(r)}\
&=prod_oprod_{pmid o}o^{psumlimits_qmu(q)sumlimits_{rmidfrac op}mu(r)leftlfloorfrac A{oq}
ight
floorleftlfloorfrac B{oq}
ight
floorleftlfloorfrac C{pr}
ight
floor}
end{aligned}
]
到目前的最后一步相比于 (2a) 的处理就爽快很多,(2a) 的 (i) 迟迟不能被化掉。不知道导致这个的本质原因是啥((
反演结束之后 (sum) 指数拆下来变成 (prod)。
[c=prod_oprod_{pmid o}prod_qprod_{rmid frac op}o^{pmu(q)mu(r)leftlfloorfrac A{oq}
ight
floorleftlfloorfrac B{oq}
ight
floorleftlfloorfrac C{pr}
ight
floor}
]
接下来又到了喜闻乐见的将 (xmid y) 换元成 (y'=xy) 时间~
[egin{aligned}c&=prod_pprod_oprod_qprod_{rmid o}(op)^{pmu(q)mu(r)leftlfloorfrac A{opq}
ight
floorleftlfloorfrac B{opq}
ight
floorleftlfloorfrac C{pr}
ight
floor}\
&=prod_pprod_rprod_qprod_o(rop)^{pmu(p)mu(r)leftlfloorfrac A{ropq}
ight
floorleftlfloorfrac B{ropq}
ight
floorleftlfloorfrac C{pr}
ight
floor}
end{aligned}
]
接下来是喜闻乐见的整除分块——枚举两个变量的乘积时间~
[c=prod_sprod_tprod_{pmid s}prod_{omid t}(so)^{pmuleft(frac to
ight)muleft(frac sp
ight)leftlfloorfrac A{st}
ight
floorleftlfloorfrac B{st}
ight
floorleftlfloorfrac C{s}
ight
floor}
]
到这儿已经可以做了,并且无法往下继续取得更优复杂度了——因为这儿的整除里面的分母有两种(不可能搞成一种的),需要的是两次整除分块,而不是二维整除分块,即先对一个变量分块,对每个块都对另一个变量分块。这样一般情况下最坏是 (mathrm O(sqrt n imessqrt n)=mathrm O(n)),在这题里面,如果先分块 (s),那么 (t) 的分子是 (dfrac ns),这和不预处理的杜教筛的复杂度分析是一样的,是 (mathrm O!left(n^{frac 34}
ight))(预处理实在是太晕了,就不搞了)。那么考虑对已经分好的每个块对该如何算贡献,那么三个整除都是常数,我们要求的是
[prod_{pmid s}prod_{omid t}(so)^{pmuleft(frac to
ight)muleft(frac sp
ight)}
]
这个显然可以用类似狄前 / 狄卷的方式预处理,只不过这样扩展到两个变量的话,需要将变量分类每类独立开来然后分别预处理,分块求值的时候就分别调用两类的前缀和 / 积作用到一起。这个式子还是不难拆的:
[prod_{pmid s}prod_{omid t}(so)^{pmuleft(frac to
ight)muleft(frac sp
ight)}=left(prod_{pmid s}s^{pmuleft(frac sp
ight)}
ight)^{sumlimits_{omid t}muleft(frac to
ight)}left(prod_{omid t}o^{muleft(frac to
ight)}
ight)^{sumlimits_{pmid s}pmuleft(frac sp
ight)}
]
预处理四个前缀和 / 积即可。预处理的话,因为计算量是线对,再加上个快速幂就是线性二次对数了。单次询问也受到快速幂的影响,变成 (mathrm O!left(n^{frac 34}log n
ight))。
总复杂度是 (mathrm O!left(nlog^2n+Tn^{frac 34}log n
ight)),常数非常大。这题模数是输入的,用了个快模,还逻辑优化了几下才勉强过了,人傻常数大啊。
贴个代码感受一下壮观。
题解写的累趴了。