给出 \(n\) 个字符串 \(s_1\sim s_n\),第 \(i\) 个字符串有权值 \(w_i\)。选出一个子序列 \(a_1\sim a_k\),满足 \(\forall\,i\in[1,k),a_i<a_{i+1}\) 且 \(s_{a_i}\) 是 \(s_{a_{i+1}}\) 的子串。求 \(\sum\limits_{i=1}^kw_{a_i}\) 的最大值。可以为空,此时权值为 \(\boldsymbol 0\)。
\(T\) 组数据,\(T\le 50\)。对于单组数据,满足 \(n\le 2\times 10^4\),\(\sum\limits_{i=1}^n|s_i|\le 3\times 10^5\)。
记 \(N=\sum\limits_{i=1}^n|s_i|\)。
考虑 dp。设 \(f_i\) 表示以 \(i\) 开头的最长子序列,则 \(f_i=\max\limits_{j\in(i,n]\land \,s_i\text{ is a substring of }s_j} f_j+w_i\)。
将所有串拼成一个大串 \(S\) 进行后缀排序。则 \(j\) 满足条件,当且仅当 \(s_j\) 中有一个后缀与 \(s_i\) 的最长公共前缀长度不少于 \(|s_j|\)。
这样的后缀排名形如一个区间 \([L,R]\)。考虑线段树维护。区间 \([l,r]\) 的信息为:当前包含排名为 \([l,r]\) 中的后缀的字符串中,\(f_j\) 的最大值。
那么转移就是区间最大值。可能会重复贡献一些 \(f_j\),但由于是取 \(\max\) 所以没关系。
转移完后在线段树上对 \(s_i\) 的所有后缀排名对应的位置进行单点修改。
时空复杂度均为 \(\mathcal{O}(N\log N)\)。可以把 \(\text{height}\) 数组用线段树维护然后线段树上二分得到排名区间,这样空间是线性。
标签:le,limits,后缀,线段,GRE,Words,区间,排名 From: https://www.cnblogs.com/MnZnOIerLzy/p/18064190