ZROI 19.07.30 简单字符串/ll

写在前面:今天下午药丸……不会字符串,全程掉线/ll


  • 给出字符串\(S\),\(q\)次询问,每次给出\(a,b,c,d\),询问\(S[a,b]\)的所有子串和\(S[c,d]\)最长公共前缀的最大值。\(|S|,q \leq 10^5\)。

取反建个SAM,每次二分答案。如果存在,合法串的右端点一定在\([a+len-1,b]\),建个主席树维护一下这些后缀在不在对应串的子树里就可以。


  • 有一个字符串\(S\),初始为空。\(m\)次操作,每次操作在第\(x_i\)次操作之后的字符串后面加上一个不超过\(k\)的字符\(c_i\),并求出新串最短的循环节,强制在线。\(m, k \leq 10^5\)。

Sol1:

发现我们要维护的就是kmp的\(next\)数组,然而kmp复杂度是均摊的,如果可持久化的话,对某个多次跳\(next\)的位置多次询问就会gg。

我们可以考虑给它严格化一下。

设\(trans_{x,c}\)表示从\(x\)后面添加一个字符\(c\),会转移到的位置。

考虑\(trans_{x,c}\)和\(trans_{next_{x},c}\)有什么不同。

如果\(next_{x}\)后面的字符不是\(c\),显然它们相等。否则\(trans_{x,c}=next_x+1\)。

对\(trans\)数组可持久化一下,每次修改一个位置即可。

Sol2:

每次跳\(next\)的时候,如果\(next_x \leq \frac{x}{2}\),就可以直接跳,因为最多跳\(\log\)次。

否则就说明\(x\)有一个长度为\(x-next_x\)的周期,在周期内不管怎么跳,后一个字符都是相等的。

那么可以直接跳到\(x~ mod~(x-next_x)\)的位置,发现最多也会跳\(\log\)次。

这样复杂度就是严格的了。


  • 长度为\(n\)的字符串,分成至少\(k\)段,使得每一段的所有子串中,字典序最大的子串最小。

首先二分答案,然后考虑倒序处理。每次在前面加入一个字符,用SA判断新增的子串是否超过二分值即可。


  • 给定一个字符串\(S\),维护一个字符串vector \(T\),支持三种操作:\(T.append(T_x+c)\),\(T.append(c+T_x)\),询问\(T_x\)在\(S[l,r]\)出现次数。\(|S|,m\leq 10^5\)。

发现\(T_x\)一定是\(S\)的子串,否则就可以把它丢掉。

对于每个\(T_x\)可以维护它在\(S\)的SAM上的节点位置,操作1和2可以直接做,操作3可以离线线段树合并或者主席树。


  • 区间本质不同子串个数。

离线扫描线。考虑每次加入新字符的时候怎么办。

先考虑暴力,假设我们在SAM里新加入了这个字符,那它新产生的子串一定是从这个新加入的节点一直跳\(fa\)跳到根,路上经过的节点。

每个节点维护一个\(lstpos\),表示最后一次跳到这个节点的位置,那么左端点在这个位置右边的询问会产生影响。

发现这个操作很像lct的\(access\)操作,所以相同的\(lstpos\)可以看作一段,均摊是\(\log\)段。每段产生的影响会形如一个分段函数,只有常数段,线段树维护即可。

总复杂度\(O(n\log^2 n)\)。


  • 区间本质不同回文串个数。

掉线了,咕咕咕。


  • 字符串\(A\)对\(B\)是好的,当且仅当\(A\)在\(B\)里出现了至少两次。给定\(S_1\),求最大的\(k\),使得存在字符串序列\(S_1,S_2,…,S_k\)满足对于任意的\(i \in [1,k)\),\(S_{i+1}\)对\(S_i\)是好的。

显然每个\(S_i\)都是\(S_1\)的子串。

一定存在一组最优解,使得对于\(i \geq 2\),任何\(S_{i+1}\)都是\(S_i\)的后缀。

证明比较显然,如果不是后缀,把后缀后面的部分去掉不会影响答案。

所以答案是SAM上的一条链,对每个点二分一下祖先就可以。


  • 给定字符串\(S\),求后缀之间两两最长回文LCP,每次在\(S\)后加一个字母,输出加字母后的答案,强制在线。

最长回文LCP,实际上就是回文树上两两之间的LCA深度。

新加入字母时,考虑它和之前所有节点的LCA深度和,发现每个祖先贡献为\(size_x\times(dep_x-dep_{fa_x})\),是个经典数据结构,LCT维护即可。


  • 求字符串\(S\)的所有子串中,任选两个,满足\(|A|+|B|-2LCP(A,B) \leq L\)的\((A,B)\)数量。\(n\leq 10^5\)。串伪随机。

这东西的意义其实就是后缀树上两个点之间路径的长度。

树分治找长度不超过\(L\)的路径总数即可。

对后缀树上的每个节点启发式合并子树也可以。

很多LCP类问题用树型结构去分析都有很好的效果。


  • 区间Border。\(n,q \leq 10^5\)。

转化为求最短循环节。发现一段区间的循环节等价于找一个\(x\),使\(x+LCP(L,L+x-1)-1\geq R\)。

从左往右跑扫描线,遇到询问的左端点就加进去。对于每个询问第一次遇到符合条件的\(i\)就可以得到答案。

LCP等于后缀树上的LCA深度。

LCA有两种情况:①\(dep_L>dep_i\),②\(dep_L\leq dep_i\)

可以从后缀树上\(i\)对应的节点往上跳,跳到一个节点的时候,需要对它的子树和祖先(对应两种情况)分别判断是否有询问满足条件,只要维护询问的最小值即可,对于满足条件的可以直接暴力删去。

可以用树剖加速这个过程,复杂度\(O(n\log^2n)\)。



少女掉线中……


  • Lyndon串

对于串\(S\),若它的最小后缀是它本身,则它是Lyndon串。等价于它是它循环移位中最小的一个。

定理:若\(u,v\)是Lyndon串,则\(u+v\)是Lyndon串,当且仅当\(u< v\)。

定理:我们可以把任意串唯一划分为\(v=v_1^{q_1}+v_2^{q_2}+…+v_k^{q_k}\)的形式,满足\(v_i\)是Lyndon串,且\(v_i>v_{i+1}\)。

构造:掉线了。

后面的例题:也掉线了。

原文地址:https://www.cnblogs.com/suwakow/p/11375066.html

时间: 2024-11-08 19:38:57

ZROI 19.07.30 简单字符串/ll的相关文章

ZROI 19.07.28 序列数据结构/jk

写在前面 dls:"我不会数据结构,但是APIO的数据结构场我写了,还是蛮简单的." T1 CF643G Sol: 有一个\(O(n\log^2n)\)的做法:假设将区间排好序,取六等分点,则答案一定覆盖了若干点,求区间第\(k\)大即可. 然而会TLE 定义绝对众数为区间中出现超过一半的数. 有一个经典的做法求绝对众数,然而它要在保证有解的时候才保证正确性. 维护当前答案和出现次数,遇到相同则\(+1\),不同则\(-1\),降为\(-1\)的时候就把当前解替换. 显然如果有解的话,

ZROI 19.07.29 线性代数入门/wq

1.高斯消元 在模意义下依然有效,对主元求逆即可. 甚至可以模合数,需要对两个方程辗转相除,复杂度\(O(n^3\log p)\). 辗转相除法只要能定义带余除法就有效. 逆矩阵:对于矩阵\(A\),定义逆矩阵\(A^{-1}\)为满足\(A\cdot A^{-1}=A^{-1}\cdot A=e\)的矩阵. 求逆矩阵可以高斯消元.设有\(A\cdot A^{-1}=e\)的形式,把\(A\)消元成单位矩阵的过程中,对方程右侧进行同样的操作. 应用:设有方程\(A\cdot x=b\)(大写字母

ZROI 19.07.31 AB班ACM

写在前面:非常感谢cjc和djh两位神仙带我,非常感谢他们给了我一次躺赢的机会. 虽然我被硬点成了代码手,但我写的基本每次都有一堆罚时.然而djh爷全部1A,tql. 题目按照一血时间升序,大致符合难度顺序. A - 10^N+7 中国剩余定理板子.由于我太菜了忘记怎么crt写了,所以码了很长时间. 有个邪道做法,由于只有三个模数,且只有第三个很大.可以枚举答案是第三个模数的多少倍,只需枚举\(17\times 107\)次. B - Coins djh爷打了个表发现\(n\geq 14\)的时

ZROI 19.07.28 组合计数/lb

T1 题意:\(n\)个变量,\(0 \leq x_i \leq c_i\),求\(\sum x_i = A\)方案数.\(n \leq 32\). Sol: \(n \leq 10\)的时候容斥很水,然而生成函数掉线了. \(n \leq 32\)的时候,dls:"显然Meet in Middle."然后我又掉线了 全世界就我不会生成函数 T2 题意:求\(0\)到\(2n-1\)的排列\(p\)的个数,使得对于任意的\(i\),\(n^2 \leq i^2+p_i^2 \leq 4

POJ3617 简单字符串

三分之一的通过率的字符串 题意为,输入一个S串,有一个空串T.对S串有两种操作,一是取出S串的头放入T串的尾,二是取出S串的尾放入T串的尾.要求是要使得T串的字典序最小. 从题意来看是一个很明显的贪心思路.那么想到这一步其实比较接近答案了,但是需要注意的一点是当S串的头和尾相同的时候,那么这个时候我们当然也希望取出更小的字符,所以就需要比较下一个字符.但是如果指向头和尾的指针都分别往里前进一位的时候,这俩字符还是相同,咋办?这个情形...对,就是回文字符串.形同“ABCDCBA”这样的字符串.这

【谜客帝国】第110届云月(庄若云&amp;月思)合擂谜会(2017.07.30)

 [谜客帝国]第110届云月(庄若云&月思)合擂谜会(2017.07.30) 主持:瓷    计分:手手 1.“接天帆影入残云”(10笔字)蚕/月思 [注:面出陈德永<客居月余归后寄友人>.残云,别解提音.] 2.“西风长笛水边楼”(9笔字)洙/月思 [注:面出张养浩<黄州道中>:长笛,象形“一”.] 3. 河间元琛最豪首(2字铁道线路名)玉昌/月思 [注:典据<洛阳伽蓝记>,“而河间王(元)琛最为豪首”:青海玉树州至西藏昌都市的铁路线称为“玉昌线”.] 4. 

C 封装一个通用链表 和 一个简单字符串开发库

引言 这里需要分享的是一个 简单字符串库和 链表的基库,代码也许用到特定技巧.有时候回想一下, 如果我读书的时候有人告诉我这些关于C开发的积淀, 那么会走的多直啊.刚参加工作的时候做桌面开发, 服务是C++写,界面是C#写.那时候刚进去评级我是中级,因为他问我关于系统锁和信号量都答出来.开发一段 时间,写C#也写的很溜.后面招我那个人让我转行就写C++和php,那时候就开始学习C++有关知识. 后面去四川工作了,开发安卓,用eclipse + java语法 + android jdk,开发前端,

poj 3077 Rounders 【简单字符串处理】

题意:就是4舍5入到最近的数. 题意有些难理解... 代码: #include <stdio.h> #include <string.h> char s[10]; int main() { int t, n; scanf("%d", &t); while(t --){ memset(s, 0, sizeof(s)); scanf("%s", s); int len = strlen(s); if(len == 1){ printf(&

简单字符串排序

简单字符串排序 Time Limit: 5000MS Memory limit: 100000K 题目描述 从键盘输入10个学生的姓名和成绩,请按字典序排列学生的姓名并输出(姓名和成绩对应关系保持不变). 输入 输入共11行,前10行每行是一个学生的姓名,最后一行是10个用空格分开的整数表示对应的10个学生成绩. 输出 输出姓名按字典序排列后的学生姓名和成绩,共10行,每个学生的姓名和成绩占一行,姓名和成绩间用逗号分开. 示例输入 Bush White Mark Jean Black Wood