1 条题解

  • 0
    @ 2025-8-24 22:44:59

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar cyffff
    Not yet for the story on the last page, it's not the end.

    搬运于2025-08-24 22:44:59,当前版本为作者最后更新于2023-02-14 21:59:16,作者可能在搬运后再次修改,您可在原文处查看最新版

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

    以下是正文


    Link\text{Link}

    题意

    nn 个序列 a1na_{1\dots n},有一个常数 AA,初始时每个序列中有一个 A+1A+1。对于序列 ss,定义 f(s)f(s) 表示最小的满足 i=1ksi>A\prod_{i=1}^ks_i>Akk。有 qq 次操作,有两种操作:

    1. i[l,r]i\in[l,r],在序列 aia_i 前端加入一个数 vv
    2. 查询 i=lrf(ai)\sum_{i=l}^rf(a_i)

    对每个 22 操作输出答案。

    n,q5×105n,q\le 5\times10^51v,A1091\le v,A\le10^9

    思路

    区间查询差分成 l1,rl-1,r 两处的前缀查询。

    考虑一个非常神秘的扫描线,对于第 tt 个操作(记作时刻 tt 的操作),如果是修改,在 ltl_t 处插入 (t,vt)(t,v_t)rt+1r_t+1 处删除 (t,vt)(t,v_t),并支持动态查询 tt 时刻的,当前前缀的答案。

    考虑设扫到 ii,现在集合内所有点对按 tt 排序,就是 aia_i 最终的形态(反过来),对于 aia_it0t_0 时刻的答案就是找到 t0t_0 在集合中的前驱 t1t_1,往前连乘多少个会大于 AA,记作 ft1f_{t_1}。记 prt,nxtpr_t,nx_t 分别表示存在于集合内的 tt 的前驱与后继,则 [t,nxt1][t,nx_t-1] 之间的答案都是 ftf_t

    考虑涉及乘法,我们会想到把 v=1v=1v1v\ne 1 分开计算。我们对每个 v1v\ne 1(t,vt)(t,v_t) 维护 (prt,vprt)(pr_t,v_{pr_t}) 之间有多少个 11,记为 ctc_t。注意到最后被插入的若干个 11 是没有算入的,这个在开头写一个区间加一,区间推平为零,区间求和的线段树 T1T_1 即可。

    现在集合里只维护了 v1v\ne 1 的操作,可以发现,只用乘 O(logA)O(\log A) 个数就会超过 AA,把这些乘到的结点的 c+1c+1 加起来就是此处的 ff

    我们需要维护一个答案序列 bbbtb_t 为当前前缀在时刻 tt 的答案总和。对集合里每个结点也维护 sts_t 表示对答案序列区间 [t,nxt1][t,nx_t-1] 还有 sts_t 的贡献没计入。查询时找到查询时刻 tt 的前驱,取出其 ss 值并加上 btb_t 即为所求。

    我们不能对每个序列 aia_i 都遍历整个集合并将 ftf_t 加入 sts_t 中。对于一些 ff 没有改变的结点,我们记录上一次加入答案的时刻 timttim_t(指最后在扫到 atimta_{tim_t} 这个序列时加入过),注意到 ff 不变,则在序列 aia_i 更新 ff 值的时候需要把 sts_t 增大 (itimt)ft(i-tim_t)f_t,更新 timt=itim_t=i

    nxtnx_t 发生改变时,我们需要把 sts_t 贡献到答案序列中,即将区间 [t,nxt1][t,nx_t-1]sts_t,将 sts_t 置零,需要支持的是单点查询,维护区间加单点求值的树状数组 T2T_2 即可。

    考虑把 (t,vt)(t,v_t) 插入到 (l,vl)(l,v_l)(r,vr)(r,v_r) 之间。我们需要先把 sls_l 贡献到答案序列中,更新 l,t,rl,t,rpr,nxpr,nx,还要更新 ct,crc_t,c_r,这需要查询 [l+1,t1][l+1,t-1] 间的 11 的个数,写个单点加区间求和树状数组 T3T_3 即可。

    考虑删除 (t,vt)(t,v_t),设 l=prt,r=nxtl=pr_t,r=nx_t,我们先把 sl,sts_l,s_t 贡献到答案序列中,改变 l,rl,rpr,nxpr,nx,把 crc_r 加上 ctc_t 即可。

    所述集合可以用平衡树(set)简单维护,其实是维护了一个支持随机插入的链表。

    时间复杂度是 O(n+m(logn+logm+logA))O(n+m(\log n+\log m+\log A))

    需要代码的还是私信吧。

    再见 qwq~

    • 1

    信息

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