1 条题解

  • 0
    @ 2025-8-24 22:05:26

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar NaCly_Fish
    北海虽赊,扶摇可接。

    搬运于2025-08-24 22:05:26,当前版本为作者最后更新于2024-06-27 19:06:28,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    给出一个理论时间复杂度 Θ(PlogP+nlogn)\Theta(P \log P+n\log n) 的算法,但是常数可能比较大。


    前面的做法和官方题解是一致的,我们可以枚举 rr,计算有多少个序列会生成 rr

    sis_i 表示 [1,R][1,R] 范围内的整数中,有多少个和 ii 在模 PP 下同余。由于 sis_i 只有两种取值,我们设较小的为 LL(较大的就是 L+1L+1)。然后统计出三个数组(其中 1i<j<P1\leq i < j <P):

    • ArA_r:表示 ijr(modP)ij \equiv r \pmod P,且 si=sj=Ls_i=s_j=L 的有序数对数量。

    • BrB_r:表示 ijr(modP)ij \equiv r \pmod P,且 sisj=1|s_i-s_j|=1 的有序数对数量。

    • CrC_r:表示 ijr(modP)ij \equiv r \pmod P,且 si=sj=L+1s_i = s_j=L+1 的有序数对数量。

    对于 r0r\neq 0,能够生成 rr 的序列数量就是

    $$R^n-n![x^n](2\text e^{Lx}-1)^{A_r}(\text e^{Lx}+\text e^{(L+1)x}-1)^{B_r}(2\text e^{(L+1)x}-1)^{C_r}\text e^{Lx} $$

    r=0r=0 很简单,数量就是 Rn(RL)nR^n-(R-L)^n

    每次暴力地 Θ(n2)\Theta(n^2) 计算,然后开个 map 存一下答案就可以通过这题了。


    官方题解用到了一个猜想:本质不同的 (Ar,Br,Cr)(A_r,B_r,C_r) 的数量是 O(P)\mathcal O(\sqrt P) 级别的。我也没能将其证明或证伪,不过通过另一种思路,可以做到更优的时间复杂度。

    我们设 ArA_r'CrC_r' 分别是 iijj 不限制大小关系的情况下,按原规则统计的数量,我们将说明:

    ArA_r' 就可以唯一确定出 BrB_rCrC_r'

    首先有一个显然的关系:Ar+2Br+Cr=P1A_r'+2B_r+C_r'=P-1
    然后还有一个是:Ar+Br=SA_r'+B_r=|S|,其中 S={isi=L , 1i<P}S=\{i \mid s_i=L \ , \ 1\leq i <P \}

    其中第二个式子中左侧的意义是:选的 ii 需要 si=Ls_i=L,而 jj 没有限制。显然对于每个 ii,都存在一个 jj 使得 ijr(modP)ij\equiv r \pmod P,所以总数就是等式右侧了。

    然后如何得到真正的 ArA_r 呢?ArA_r' 减去 i2r(modP)i^2\equiv r \pmod Psi=Ls_i=L 的解的个数就是 2Ar2A_r,由此也直接得到 Ar2Ar2 A_r'-2A_r\leq 2。对于 CrC_r 的计算也是一样的。

    至此,聪明的你能想到接下来该怎么做吗?


    我们设:

    $$F(i,j,k)=n![x^n](2\text e^{Lx}-1)^{(k-i)/2}(\text e^{Lx}+\text e^{(L+1)x}-1)^{|S|-k}(2\text e^{(L+1)x}-1)^{(P-1-2|S|+k-j)/2}\text e^{Lx} $$

    其中 i,j{0,1,2}i,j \in \{ 0,1,2\}。对于每组 i,ji,j 我们都能以 Θ(PlogP+nlogn)\Theta(P \log P+n \log n) 的时间复杂度计算出所有 F(i,j,k) (0k<P)F(i,j,k) \ (0\leq k< P),因为这是经典问题

    这样对于每个 rr,能生成 rr 的序列数量就是 RnF(Ar2Ar,Cr2Cr,Ar)R^n-F(A_r'-2A_r,C_r'-2C_r,A_r')

    最后我们还要快速算出所有 ArA_r',这个做法也在 [SDOI2015] 序列统计 中出现过了。我们只需要把所有 si=Ls_i=Lii 取离散对数,然后计算一次卷积即可。


    update:我们实际上并不需要对每组 (i,j)(i,j) 都计算,因为可能出现的 (i,j)(i,j) 只有 (0,0),(0,2),(1,1),(2,0)(0,0),(0,2),(1,1),(2,0) 四种,由此也可以保证计算幂级数的乘方时,指数必定是整数,实现上会方便一些。

    • 1

    信息

    ID
    3963
    时间
    3000ms
    内存
    500MiB
    难度
    7
    标签
    递交数
    0
    已通过
    0
    上传者