CF1450G

CF1450G [* hard]

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

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

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

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

\(|S|\le 5000,a\le b\le 10^5\)

Solution

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

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

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

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

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

对于第一类操作,当前仅当点集 \(f_{S\land\{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\) 对应的状态均为一棵树,那么我们有这样的结论:我们可以通过调整将 \(\{S\cap T\}\) 这样的一个森林调整为一棵树。

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

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

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

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

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

posted @ 2020-12-24 22:00  Soulist  阅读(146)  评论(0编辑  收藏  举报