字符串杂题

A.CRB and String

 考虑 (S) 能变成 (T) 首先需要 (S)(T) 的子序列且 (S_0=T_0)

 然后考虑不同的限制会影响什么,发现只会影响最开始连续一段相同的字符

 那么只需要 (T) 开头连续相同字符数 (le) (S) 开头连续相同字符数

B.Fleet of the Eternal Throne

 考虑每次对给定的两个串建 (AC) 自动机

 然后用每个串在这两个 (SAM) 上匹配前缀的最长匹配

 两个串取 (min) 所有串取 (max)

C.Classic Quotation

 显然的答案分成两部分,即组合而成和本来就有

 本来就有的可以直接前缀和来得到,考虑组合而成

 同样的,记录每个位置匹配长度为 (k) 的前缀和也可以得出

D.string

 考虑以 (a) 为前缀在原串的后缀之中可以代表一段 (rank) 区间

 那么以 (b) 为后缀在反串的后缀之中可以代表一段 (rank) 区间

 用 (sa) 求出区间,问题转化为二维数点问题

 主席树求一下答案

 还有一个问题是前后缀会重叠,那么可以直接枚举长度来减掉

E.迷失的字符串

 考虑一个串的时候可以直接树形 (dp)

 发现总长和个数同级,考虑直接把所有串连起来 (dp)

 写出柿子发现可以用 (bitset) 优化

F.Subsequence

 考虑如果选出来的串是 ([l,r]) 那么对于子序列的开头结尾 (L,R),有 (L<l或R>r)

 那么如果 (L<l) 发现 (r) 一定可以延伸到 (n)(R>r) 同理

 所以最长次连续子串一定是前缀或后缀

 考虑求 (le w) 的方案数

 最长次连续子串 (le w) 则需要满足开头 (len-w) 个字符不同且结尾 (len-w) 个字符不同

 在 ([w,k+w]) 枚举 (len),根据是否重叠统计一下方案就行

&nbsp;

G.序列

 考虑离线从小到大枚举 (d)

 字典序第 (k) 的相当于在字典树上访问到的第 (k) 个后缀

 发现改变一个数的相对大小相当于把树上以这个数为边权的边的子树 (dfs) 序整体改变

 用平衡树维护一下 (dfs)

H.残缺的字符串

 设 (*=0) 定义 (f(A,B)=sum(A_iB_i(A_i-B_i)^2))

 拆一下 (fft) 就行了

I.str

 考虑枚举 (A,B) 不同的位置 (i,j)

 那么答案就是 (max(lcs(i-1,j-1)+lcp(i+1,j+1)+1))

 考虑从大到小枚举 (lcp) 那么需要考虑区间的启发式合并

 那么对每个区间维护 (rank)(set),合并的时候对前驱和后继求一下就行了

J.

 先把所有串建出 (AC) 自动机

 考虑两种情况

 首先是没有走过 (fail) 边的方案,这个可以很简单得到

 然后考虑走过 (fail) 边的方案

 设 (dp[i][j][k]) 第一次失配在 (k),之后走了 (i) 匹配到点 (j) 方案数

 那么我们只需要转移时保证 (dep[j]> i)

 发现 (k) 没什么用,直接设 (dp[i][j]) 第一次失配之后走了 (i) 匹配到点 (j) 方案数

 转移保证 (dep[j]>i) 就行了

原文地址:https://www.cnblogs.com/mikufun-hzoi-cpp/p/12730398.html