1 条题解

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

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar mrsrz
    故障机器人

    搬运于2025-08-24 22:26:52,当前版本为作者最后更新于2021-01-04 17:13:36,作者可能在搬运后再次修改,您可在原文处查看最新版

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

    以下是正文


    5×1055\times 10^5 已成为常见的根号复杂度范围.jpg

    本题可以分为两个部分,下面分别对其分析。

    • 第一部分(预处理)

      我们对每个不同的数值进行考虑。考虑当前的数为 vv,它的出现次数为 cc

      由于 vv 能产生贡献的区间的中点位置必须是 vv,因此我们考虑枚举两个端点到中点的距离 LLvv 在区间的出现次数显然随着 LL 的增大而单调不降,且出现次数为 0c0\sim c

      我们再对 vv 的每个不同的出现次数进行考虑。对于 vv 出现了 ii 次,它对应的 LL 是连续的,设为区间 [l,r][l,r]。我们可以找到一个 m[l1,r]m\in[l-1,r] 满足当 L[l,m]L\in[l,m] 时,vv 是区间的众数,而当 L[m+1,r]L\in[m+1,r] 时,vv 不是区间的众数。证明很简单,这里略去。

      因此我们可以使用二分来找到这个 mm 的值,从而能得出所有能产生贡献的 LL 的范围。由于总共有 cc 个不同的出现次数(00 次不可能成为众数,故略去),因此可以得到 cc 个互不相交的范围。

      由于二分的时候还需要求区间众数,因此对于一个 vv,求它的 LL 的范围需要 O(cnlogn)O(c\sqrt n\log n)O(cnlogn)O(c\sqrt{n\log n}) 的时间复杂度。而所有的 vvcvc_v 的和为 nn,因此这部分的总时间复杂度为 O(nnlogn)O(n\sqrt n\log n)O(nnlogn)O(n\sqrt{n\log n})。这个复杂度还不能接受。


      考虑优化上述过程。

      容易发现,cv>nc_v\gt \sqrt n 的不同的 vv 最多有 n\sqrt n 个,这部分我们可以暴力枚举 LL 并进行判断,时间复杂度 O(nn)O(n\sqrt n)(记得把连续的 LL 并成一个区间,否则空间复杂度将为 O(nn)O(n\sqrt n))。

      而对于 cvnc_v\leq \sqrt n 的所有 vv,我们不妨考虑枚举众数的出现次数。

      假设当前众数的出现次数为 (k1)(k-1),我们可以在 O(n)O(n) 内求出 p1..np_{1..n},其中 pip_i 表示最小的满足 [i,j][i,j] 的区间众数出现次数为 kkjj

      以下是求数组 pp 的方法:

      可以证明 apia_{p_i} 是区间 [i,pi][i,p_i]唯一众数,否则 [i,pi1][i,p_i-1] 的众数的出现次数也为 kk

      同理,若 aiapia_i\neq a_{p_i},则 [i+1,pi][i+1,p_i] 的众数的出现次数也为 kk

      我们对一个 [i,pi][i,p_i] 的左端点不断按此法向右移动,得到的 [j,pi][j,p_i] 会满足 aj=apia_j=a_{p_i},即 pip_i 是位置 jj 之后第 (k1)(k-1)aja_j

      考虑令 qiq_i 表示 ii 之后第 (k1)(k-1)aia_i 的出现位置,那么对于一个 ii,就有 pi=minj>iqjp_i=\min_{j>i} q_j

      也就是说 pip_iqiq_i 的后缀 min\min 数组。

      用 vector 按顺序存每个数值的出现位置,然后再对每个位置记一下它在 vector 里的下标,就可以 O(1)O(1) 得到单个 qiq_i

      那么这部分的时间复杂度为 O(n)O(n)

      枚举可能的数值 vv,并取出 l,rl,r 满足当且仅当 L[l,r]L\in[l,r] 时,vv 的出现次数恰好为 kk

      我们在上面提到了二分这个 mm,在二分的时候,我们需要判断的其实是,是否存在一个区间 [s,t][vm,v+m][s,t]\in[v-m,v+m] 满足 [s,t][s,t] 的区间众数大于等于 kk。而我们只需要对所有的 i[vm,v+m]i\in[v-m,v+m] 检查:满足 [i,j][i,j] 的众数出现次数恰好为 kk 的最小的 jj 是否大于 v+mv+m,这个 jj 就是上面我们求出的 pip_i。而由于 pip_i 具有单调性,因此我们只需要检查 pvmp_{v-m} 是否大于 v+mv+m 即可。因此单次检验是 O(1)O(1) 的,一次二分的复杂度就是 O(logn)O(\log n)

      由于所有的 vvcvc_v 总和为 nn,因此这里的二分的次数不会超过 nn 次,时间复杂度为 O(nlogn)O(n\log n)

      而我们需要对每个 knk\leq \sqrt n 计算对应的 pp 数组,因此这部分的时间复杂度是 O(nn)O(n\sqrt n)

    • 第二部分(回答询问)。

      我们接下来需要解决的问题如下:

      给定不超过 nn 个三元组 (v,x,y)(v,x,y) 满足 xyx\leq y。对每个三元组,枚举 i[x,y]i\in[x,y],并令 Avi,v+iA_{v-i,v+i} 增加 11

      mm 次询问,每次给定 l,rl,r,求 i=lrj=lrAi,j\sum\limits_{i=l}^r\sum\limits_{j=l}^r A_{i,j} 的值。

      这个问题有多种做法,这里介绍一种较方便且容易理解的做法(感谢 memset0 提供了该做法的思路)。

      上面这个二维的问题是比较容易想到的转化后的题意,不过我们还是直接讨论一个三元组 (v,x,y)(v,x,y)l,rl,r 的贡献。

      aa[vy,vx][l,r][v-y,v-x]\cap[l,r] 的长度,bb[v+x,v+y][l,r][v+x,v+y]\cap[l,r] 的长度,则贡献为 min(a,b)\min(a,b)

      mid=l+r2mid=\lfloor\frac{l+r}2\rfloor,可以发现,当 midvmid\leq v 时,总有 aba\geq b,当 mid>vmid\gt v 时,总有 a<ba\lt b

      那么我们对 midvmid\leq vmid>vmid\gt v 两种情况分开统计贡献即可。每种情况都是一个简单的二维数点问题,使用离线树状数组解决即可,时间复杂度 O((n+m)logn)O((n+m)\log n),空间复杂度 O(n+m)O(n+m)

    综上,算法的时间复杂度为 O(nn+mlogn)O(n\sqrt n+m\log n),空间复杂度为 O(n+m)O(n+m),可以通过本题。

    • 1

    信息

    ID
    5862
    时间
    2500ms
    内存
    128MiB
    难度
    7
    标签
    递交数
    0
    已通过
    0
    上传者