• CF1450G


    CF1450G [* hard]

    给定字符串 (S),保证不存在 t,r,y,g,u,b,即字符集 (mathbf{Sigma})(20)

    给定常数 (k=frac{a}{b}),你可以执行以下操作:

    • 选择字符 (c),设其出现集合为 ({i_1,i_2...i_m}),则当 (kcdot (i_m-i_1+1)le m) 时,可以将 (c) 改成任意一个当前字符串 (S) 中存在的字符。

    假定经过若干次操作,最后可以使得整个串变成一个字符,那么称此字符合法,求所有合法的字符。

    (|S|le 5000,ale ble 10^5)

    Solution

    考虑假设我们执行了操作 (x o y),则连接 (y o x),则最后的图必然是一棵树。

    (f_{S}) 表示当前得到了点集 (S) 且集合 (S) 能够继续操作,此时 (f_S=1)

    我们先预处理点集 (T) 能否操作,设数组为 (g)

    考虑我们的操作只有两种:

    1. 给当前森林增加一个根。
    2. 用两棵森林拼接得到当前点集。

    对于第一类操作,当前仅当点集 (f_{Sland{y}})true(g_{S}=1) 时其为 true

    对于第二类操作,转移为枚举子集 (S),当前仅当两者均为 true 时其为 true

    于是我们得到了一个 (mathcal O(3^{mathbf{|Sigma|}}+n)) 的做法。

    接下来有一个很强的性质,考虑第二类转移,设 (mathbf{range(S)}) 表示点集 (S) 的元素构成的区间,则可以发现,对于第二类转移,我们只需要转移 (mathbf{range(S)},mathbf{range(T)}) 不相交的部分。

    证明如下:

    首先可以假设 (S,T) 对应的状态均为一棵树,那么我们有这样的结论:我们可以通过调整将 ({Scap T}) 这样的一个森林调整为一棵树。

    首先因为 (S,T) 满足限制,于是显然有 (g_{Scap T}=1)(考虑到长度更小,元素更多)

    于是我们可以将原 (S) 的根拿出来,并考虑将 (T) 接在下来,显然这可以到达且合法。

    接下来考虑假设 (S,T) 均为森林,我们考虑若干棵树并在坐标上进行排布,任意一对的相交都可以执行上述性质变成不相交的情况,于是我们只需要依次转移不相交的情况即可得到答案。

    于是我们按照左端点排个序,对于第二类转移只需要检查 ({c_1,c_2...c_i}cup S) 即可。

    tips:元素 (c) 合法当且仅当 (f_{mathbf{All}land c}) 合法。

  • 相关阅读:
    【转】Unity学习笔记——MonoBehaviour类Invoke, Coroutine
    【转】Unity3D协同程序(Coroutine)
    Java定时任务
    SMSLib开发指南
    短信猫JAVA二次开发包SMSLib,org.smslib.TimeoutException: No response from device解决方案
    注解+反射+JDBC,实现一个简易的泛型DAO接口
    利用Window超级终端,修改短信猫波特率
    深入理解JDK动态代理机制
    深入分析Java ClassLoader原理
    Linux内核升级指南
  • 原文地址:https://www.cnblogs.com/Soulist/p/14186608.html
Copyright © 2020-2023  润新知