20240904:字符串选做

P4555 [国家集训队] 最长双回文串#

题意:给定字符串 s,找到他最长双回文串 t 的长度。双回文串定义为存在一个 i>1 使得 t[1,i)t[i,n] 都是回文串。|s|105

二分哈希求出所有回文中心的半径,设以 i 为中心的最长回文串为 [li,ri]

我们发现当两个回文中心确定时,最长双回文串的长度唯一确定(左边界向左延伸一格必须先使右边界往里缩一格,否则左右两串出现重叠)。

枚举回文中心 i,找到一个最小的 j 使得 rjli1,显然可以树状数组维护,在 ri 的位置加入 isubmission

P3546 [POI2012] PRE-Prefixuffix#

题意:定义 st循环相同的,当且仅当 s 能够将一个后缀移到开头使得与 t 完全相同。

给出字符串 s,找到最大的 in2 使得前缀 prei 和后缀 sufi 是循环相同的。

枚举 s 的 border i,再找 s[i+1,ni] 的最长不重叠 border,令 si=s[i+1,ni],发现把 si 的 border 掐头去尾就是 si+1 的 border。

反过来讲,有 Bmax(si)Bmax(si+1)+2,设 p=Bmax(si),当 ii1 时,令 pp+2,然后不断减 1 直到合法,势能分析可以得出是线性的。

submission

更加巧妙的做法:把 s 重排成 s1sns2sn1,那么两个 border 就是最靠前的两个相邻回文串(长度皆为偶数),和上题一样维护。

Minimal String Xoration#

题意:给定一个长度为 2n 的字符串 s,选出一个 k[0,2n) 使得满足 ti=sik 的字符串 t 的字典序最小,输出 tn18

f(k,i) 表示选了 k 得到字典序最小的 t2i 的前缀,显然有 f(k,i)=f(k,i1)+f(k2i1,i1)+ 表示拼接。

类似后缀数组 O(nlogn) 构造,求出 f(k,i1)f(k2i1,i1)i1 时的排名就可以当做两位数排序。

时间复杂度 O(n22n),基数排序可以省掉一个 nsubmission

x-prime Substrings#

题意:定义只有数字组成的字符串 sx-prime 的当且仅当 si=x 且不存在一个子串和是 x 的真因子(不是他本身)。

给定字符串 s 和正整数 x,求 s 至少要删掉多少字符才不存在一个子串是 x-prime 的。|s|1000,x20

注意到 x 很小,满足 x-prime 的字符串应当也很少,称之为非法子串。

删多少字符才能不存在非法子串的这类问题很容易想到构造 ac 自动机,最坏情况下,所有非法串构成的字典树大小只有 S=4853

f(i,s) 表示前 i 个字符匹配到 ac 自动机的状态 s 时需要删多少个才合法,枚举 i 删不删,时间复杂度 O(|s|S)submission

P7361 「JZOI-1」拜神#

题意:给定字符串 sq 次询问 s[l,r] 出现至少两次的最长子串长度。n5×104,q105

考虑询问的本质,长度 L 合法等价于存在 i,j[l,rL+1] 满足 lcp(sufi,sufj)L,可以二分。

后缀排序求出 height 数组,hi=lcp(sufsai,sufsai1),考虑 sufsaisufsai1 连边,那么 L 合法就是加入所有 hL 之后 i,j 在同一连通块。

维护 nxti 表示与 i 在同一连通块的大于 i 的最小后缀编号,这个东西可以并查集的启发式合并实现,每个连通块开个 set 维护所有编号。

那么长度 L 到底怎么判断呢?区间查询 [l,rL] 当中最小的 nxti 是否 rL+1,显然可以线段树。

你当然可以离线。也可以维护持久化线段树 Ti 表示加入所有 hi1nnxt 值,时空复杂度皆为 O(nlog2n)submission

REPEATS - Repeats#

题意:求连续出现次数最多的重复子串的连续出现次数,多测。T20,n50000

枚举重复子串长度 L,每隔 L 放置一个关键点 L,2L,3L(1-base)。

如果一个子串是 k-repeat 的,那么他一定恰好覆盖 k 个关键点。 这个 k 显然是可以二分的,考虑怎么 check。

单调队列维护长度为 k 的窗口内关键点所代表后缀以及前缀的排名,方便通过正串和反串的后缀数组求出 LCP 和 LCS(suffix)。

出现 (k, L) - repeat 当且仅当 tor+tol1L,其中 tor 表示当前窗口内关键点表示后缀的 LCP。

枚举 L 填关键点是一个调和级数,直接做是双 log 的。

考虑一个关键点区间 pl,pl+1pr,如果 tor+tol1 不小于 L,则称 [l,r] 是优秀的。显然如果 [l,r] 是优秀的,任意其子区间也是优秀的。

[l,r] 为右段点是 r 是的极大优秀区间,如果 [l1,r+1] 优秀则 [l1,r] 优秀,与 l 是极小左端点矛盾。因此 rr+1 时左端点单调不降。

双指针代替二分,时间复杂度 O(nlnn)submission

P5115 Check,Check,Check one two!#

题意:给定字符串 s 以及正整数 k1,k2,求:

i<j[lcp(i,j)k1][lcs(i,j)k2]lcp(i,j)lcs(i,j)

数据范围:k1,k2n105

由于 (i,j) 对于 lcp 和 lcs 都是相同的,我们把他们接在一起,统计 ilcs+1 处的 lcp。

如果 lcp(i,j)=Lsi1sj1,那么他对答案有 F(L) 的贡献,其中:

F(L)=p=1L[pk1][Lp+1k2]p(Lp+1)

可以 O(n) 预处理。

考虑 si1sj1 的限制,否则相同子串不是极长。正难则反,容斥减掉 si1=sj1=az 的情况。

问题转化为与 (i,j) 的 lcp 相关的一个式子,根据 sa 的经典套路,在 height 数组上单调栈维护 j<i[ssaj1=ch]F(minj+1ih)submission

P8147 [JRKSJ R4] Salieri#

题意:给定 n 个串 si 以及其权值 viq 次询问,每次给出一个文本串 t,设 cnti 表示 sit 中的出现次数,求 cnti×vi 的第 k 大值。

数据范围:|s|5×105,n,m105,kn

把文本串放在原串 ac 自动机上跑,走到一个状态则将其 tag 加一,最终 cnti 等于 si 的终止节点所表示状态在失配树上的子树和。

考虑对所有走过的状态建出虚树,由于一共只走 |t| 步,虚树规模也是 O(|t|) 的。

不难发现 x 与其虚树上的父亲 fa (不含)之间路径的 cnt 都是一样的,也就是说,我们把整棵失配树划分为 O(|t|)cnt 相同的链。

二分答案 mid,问题转化为有多少结束状态满足 vimidcnticnt=0 趋向正无穷,忽略),树上主席树实现,时间复杂度 O(|t|log|si|logV)

submission

String Journey#

题意:给定字符串 s,找到最大无交子串集 T 的大小,满足 titi1 的真子串(非本身)。

首先,将字符串翻转,限制转化为 ti1ti 的真子集。

观察1:如果大小 k 合法,一定存在一组方案解使得 |ti|=i

由于是真子串,显然有 |ti|i。考虑找到第一个长度大于 i 的位置,删掉前后缀使之成为 i,不会影响整个方案的合法性。

fi=k 表示长度为 i 的前缀,强制使 si 等于 tk 的结尾的最大合法长度。

观察2(i1)fi1+1ifi+1

对于任意 i 的方案,删掉 t1 ,删掉 ti>1 最后一个字符,能够得到一组 i1 的长度为 k1 的方案。即 fi1fi1,与结论等价。

l=rfr+1,即前缀 r 最优方案 tk 的左端点。

我们称 [l,r] 合法,当且仅当他是 r 一组方案的 tk,注意这里的方案需要满足 |ti|=i,不难发现若 [l,r] 合法,则所有 [l,r] 的后缀合法。

根据观察2可知,随着 r 的增大,l 单调不降。考虑从 [l,r1][l,r]

[l,r] 合法当且仅当存在一个合法串 [l,r] 满足 r<l 且与 [l+1,r][l,r1] 之一相同。

考虑在 SAM 上对于每个状态 p 维护该状态所有右端点小于 l 的合法串的最大长度 gp

那么 [l,r] 合法等价于 [l+1,r][l,r1] 对应的状态中 gp 的最大值大于等于 rl,如果合法则跳过。

否则 ll+1,此时需要更新所有右端点等于 l 的合法字符串,其中左端点范围是确定的 [lfl+1,l]

p 表示 [lfl+1,l] 的状态,现将 gpfl 取 max,然后往上跳 p 的祖先,如果 gp 已经是 L(p) 了,不需要再往上跳;否则 gpL(p)

时间复杂度均摊 O(n)。(一共就 O(n) 个状态,每个状态被更新至多 2 次)submission

Everybody Lost Somebody#

题意:

Speckled Band#

posted @   Lu_xZ  阅读(30)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示