zoukankan      html  css  js  c++  java
  • 「总结」$pdf$课: $string$

    今天做了个(LCT+PAM),果然还是字符串最毒瘤啊毒瘤毒瘤毒瘤啊。

    1.CRB and String
    首先我们的(S)应当是(T)的自序列,且第一个字符一样。
    由于字符不能相同的限制,我们需保证(T)开头的连续相同字符小于等于(S)开头连续相同字符。
    这样才能得到(T),否则不能。

    2.Fleet of the Eternal Throne
    我们对((x,y))建后缀自动机。
    然后跑每一个串的前缀。
    然后对(x,y)的答案分别取(min),每一个串再分别取(max)即可。

    3.字符串计数
    相当于这样一个过程:
    每次加入一个(T)的子串,使得这个子串不可以和已经加入的子串构成更长的子串。
    那么对(T)(SAM),在(WDAG)上做(dp),求出(dp[i][j])为最短的以(I)开头,接上(j)后产生的串不是(T)的子串的字符串长度。
    那么我们可以二分答案,然后用矩阵快速幂来(check)
    具体来说,可以发现上述过程其实就是从一个(1)链接的节点到另一个(1)链接的节点。
    那么我们可以做一个佛洛依德然后用矩阵快速幂来加速。
    如果最终求出的长度是大于等于(n)的那么我们的答案需要更小。

    4.Classic Quotation
    相当于找出(s[1:i],s[j:n])分别的贡献和跨越中间的贡献。
    前两个只需要找出出现位置然后求个前后缀和即可。
    后面那个我们只需要枚举(s[1:i])中出现的长度(k),然后求出长度(k)出现的位置。再求前后缀和即可。

    5.String
    等价于求前缀为(s),后缀为(t)(lengeq|s|+|t|)的方案。
    如果不考虑长度,我们将正反串按照字典序编号,(s,t)分别对应一些编号区间,可以用字典树来求出区间,然后用主席树来统计答案。
    然而要扣掉长度不足的串,离线+枚举长度来确定。

    6.迷失的字符串
    把所有的串拼到一起,(f[x][i])表示节点(x)的子树中某点到当前节点能否和某个字符串的(s[L_{id}:j])匹配,在拥有(j)的情况下就可以确定出(id)是多少了。
    然后(g[x][I])表示(x)前往子树中能否和某个字符串的(s[L_{id}:j])匹配。
    转移直接上(bitset)优化即可。

    7.String
    (dp[i][j][k])为当前在(i),和第一个串匹配的长度为(j),和第二个串匹配的长度为(k),期望停下来的步数。
    然后枚举下一个字符直接转移就可以了。
    转移存在环,分层转移+分层高消即可。
    注意判无解只需要高消可能转移到(f[1][0][0])的点即可。

    8.Subsequence
    如果最长次连续子串是([l:r]),那么找到非子串子序列开头和结尾(L,R),那么存在:(L<l||r<R)
    这样的话我们就可以把子串增长(r ightarrow n)或者是(1leftarrow l)这个样子。
    这样我们的最长次连续子串一定是前缀或者后缀。
    (f(w))为长度小于等于(w)的方案即可差分出解。
    发现最长次连续子串长度(leq w),那么开头和结尾的(len-w)个分别各不相同。
    然后分类讨论(len)的长度来决定对(f(w))的贡献即可。

    9.隐身术
    考虑暴力搜索。
    (dp[x][y][z])(A)(x)开始以后的部分和(B)(y)开始以后的部分,之前的编辑距离为(z),可以求出(lcp)然后(x,y)直接向右跳。跳过去之后就有三种状态的选择了:

    [dp[x+1][y][z+1],dp[x][y+1][z+1],dp[x+1][y+1][z+1] ]

    如果(x=|A|+1)并且(zleq K),那么(y-1)就是合法的右端点。

    10.序列
    (SAM)求出后缀树,然后按照(d)的变化从小到大来做。字典序第(k)消相当于按(dfs)序列访问到的第(k)个后缀,每次改变一个数的相对大小,就是从后缀树上截所有以这个数为边的子树,相当于分离子树然后插入子树,用平衡树维护(dfs)序列就可以了。

    11.残缺的字符串
    (*)(0),(f(A,B)=sumlimits_{i=1}^{m}A_iB_i(A_i-B_i)^2)
    那么(A=B)当且仅当(f(A,B)=0)
    (A_iB_i(A_i-B_i)^2)拆开得到了(A_i^3B_i+A_iB_i^3-2A_i^2B_i^2)
    我们可以直接(FFT)求这个东西的和。
    然后求出每一个位置是否能够匹配。

    12.Str
    枚举(i,j)为不同位置。
    那么就是(ans=maxlimits_{i,j}{lcs(i-1,j-1)+lcp(i+1,j+1)}+1)
    考虑优化。
    我们从小到大枚举(lcp),如果是(lcp=x),那么把(height>=x)的区间启发式合并。
    最后选的(i,j)必然属于同一个区间,才能够让(lcp>=x),同时我们要最大化(lcs)对于每一个区间维护一个反串(rk)(set),插入的时候把点和前驱后继求个(lcs),这样可以维护最大的(lcs)了。
    复杂度就是(O(nlog^2n))的。

    13.串
    (dp[i][j])为第一次匹配失败之后匹配了(i)个字符,当前在(j)的方案。
    暴力转移复杂度就是对的。

    14.扭动的回文串
    前两个直接用马拉车求一下,后一个枚举中心然后二分(hash)求出最长回文串。

  • 相关阅读:
    【java】详解java多线程
    【java】switch case支持的6种数据类型
    【Java】详解java对象的序列化
    【java】详解I/O流
    【java】自定义异常类
    【java】详解集合
    【NotePade++】NotePade++如何直接编译运行java文件
    【java】JVM的内存区域划分
    Unicode和UTF的关系
    【java】解析java中的数组
  • 原文地址:https://www.cnblogs.com/Lrefrain/p/12638875.html
Copyright © 2011-2022 走看看