• ZROI 19.08.12模拟赛


    传送门

    写在前面:为了保护正睿题目版权,这里不放题面,只写题解。


    “我发现问题的根源是大家都不会前缀和。”——敦爷


    • A

    敦爷spj写错了,差点把蒟蒻swk送走

    (50pts:)

    考虑不输出方案怎么做。显然是树形dp。

    (f_{i,j,{0/1/2}})表示(i)的子树中,有(j)条链,根节点状态为:({)没选(/)选了向下的一条链(/)选了向下的两条链(})的最优解。

    对于一棵子树,开始时只考虑根节点,依次合并每个儿子。合并时需要枚举父亲和儿子的状态,用(size)限制枚举上界,可以证明复杂度是(O(nk))的。

    转移的时候分别讨论各个状态之间的转移即可。

    (100pts:)

    输出方案也不难,只需要记录每个状态依次从哪个儿子的哪个状态转移来即可。

    可以把转移方向放在儿子上,避免复杂的可持久化。

    当然写起来就是另一回事了

    复杂度证明:

    合并大小分别为(x,y)的两棵子树,复杂度为(O(min(x,k)cdot min(y,k)))

    不妨设(xgeq y),对两棵子树的三种情况分别分析。

    (xgeq k, ygeq k),则单次复杂度(O(k^2)),但这样的子树最多(frac{n}{k})棵,总复杂度(O(nk))

    (xgeq k, y < k),发现每个节点最多合并进(sizegeq k)的子树一次,即整棵树上每个零散节点最多产生(O(k))的复杂度,总复杂度(O(nk))

    (x<k,y<k),对于一个节点,最多与(O(k))个节点合并后,子树大小就会(geq k),因此每个节点最多产生(O(k))的复杂度,总复杂度(O(nk))


    • B

    (60pts:)

    对于一次操作([x,y]),区间([l_i,r_i])被访问的充要条件是:([x,y])([l_i,r_i])有交;([x,y])不完全包含([l_i,r_i])的父亲。

    由此可以得到一个(O(nq))的算法,即对线段树上的每个节点分别统计访问次数。实现时有很多分类讨论,比较复杂。

    (100pts:)

    对于(O(nq))算法里的分类讨论,每种讨论实际上都可以提取出一个关于(x,y)的低次多项式。

    发现如果区间([l_i,r_i])([x,y])包含,则它的每一个子区间都被其包含。因此整个子树可以规避分类讨论,预处理多项式系数即可。

    即询问时遇到完全包含的节点可以直接退出,复杂度等同于线段树区间询问,(O(n+qlog n))


    • C

    (60pts:)

    发现(h_{i+1}-h_i)等于(i)位置结束的每个子串的(G_i)之和,即([1,i])每个前缀的末尾增加了一个字符。

    (n)个后缀拉出来跑kmp,维护一下前缀和即可。

    (100pts:)

    对于字符串(A)(f_i)的含义其实是(A[1…i])的border(相等的前后缀)个数。

    由此得到(G_A)的含义是(A)的每个前缀出现的次数(-1)之和,因为每次枚举到这个前缀第一次出现以外的位置时,都会产生一次border的贡献。

    再考虑(h_{i+1}-h_i),即(sum_{j=1}^i G_{S[j…i]})的意义,发现对于(S[1…i])的每个子串,设其出现次数为(d),产生的贡献为(frac{d(d-1)}2)

    用后缀自动机维护,每次加入新字符时,等价于(fail)树上到根节点的链(+1),可以离线树剖或者LCT维护。

  • 相关阅读:
    力扣 136. 只出现一次的数字
    剑指 Offer 24. 反转链表
    javaWeb8——jdbc总结,JDBC调用存储过程和存储函数:CallableStatement
    剑指 Offer 53
    剑指 Offer 53
    使用 .NET Core 3.x 构建 RESTFUL Api
    SqlServer 多表连接、聚合函数、模糊查询、分组查询应用总结(回归基础)
    SqlServer 查询的几种方式以及数字函数、时间函数的应用总结(回归基础)
    关于SqlServer表结构 2(回归基础)
    关于SqlServer那些事1(回归基础)
  • 原文地址:https://www.cnblogs.com/suwakow/p/11375094.html
Copyright © 2020-2023  润新知