zoukankan      html  css  js  c++  java
  • P5518

    做 /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)),常数非常大。这题模数是输入的,用了个快模,还逻辑优化了几下才勉强过了,人傻常数大啊。

    贴个代码感受一下壮观。

    题解写的累趴了。

    珍爱生命,远离抄袭!
  • 相关阅读:
    ArrayList集合 、特殊集合
    二维数组 、多维数组
    一维数组
    类:String,Math,DateTime,Random
    while做法1.兔子生兔子 2.求100以内质数的和3.洗发水15元 牙膏5元 香皂2元 150元的算法
    博客迁移
    [WC2008]游览计划 「斯坦那树模板」
    [SDOI2009]HH去散步 「矩阵乘法计数」
    [HNOI2007]梦幻岛宝珠 「套路:分层 $DP$」
    多项式求逆
  • 原文地址:https://www.cnblogs.com/ycx-akioi/p/solution-p5518.html
Copyright © 2011-2022 走看看