POJ2774 Long Long Message 【SAM】】的更多相关文章

POJ2774 Long Long Message 找两个串的最长公共字串 对其中一个串\(s\)建\(SAM\),然后我们如何找到最长公共字串,办法就是枚举\(t\)串所有的前缀,然后找各个前缀的最长能和\(s\)串匹配的后缀. 如果一个个跑需要\(O(n^2)\),\(SAM\)可以来保存之前匹配的状态,假设现在匹配的状态是\(u\),匹配到的最长后缀长度为\(l\),那么现在考虑在当前状态后面加上一个字符,也就是成为\(t\)串一个新的前缀,那么最大能匹配的必然是在上一次匹配到的最长串的基…
[题目大意] 求两个字符串的最长公共子串. [思路] 对第一个字符串建立后缀自动机,第二个字符串去匹配.cnt记录当前最长公共子串的长度,而ret记录答案. p代表位置指针,初始在rt位置. 对于第二个字符串的某一位s[i],如果当前有s[i]孩子,则cnt+1,继续往后移动:否则沿着pre指针返回.如果pre指针返回到0,则将p回到rt,cnt清空为0;否则如果中间有点拥有s[i]孩子,cnt=step[]+1. 为什么cnt=step[]+1?不要忘了后缀自动机的本质是维护后缀,沿着pre指…
[题目大意] 求一个循环数列的最小表示法. [思路] 最小表示法的正解:★ SAM乱搞,和前面的POJ那道一样.然而MLE了,当作学习一下map的用法^ ^ map的使用方法(来源:☆) 一.map的说明    1   头文件   #include   <map>     2   定义   map<string,   int>   my_Map;   或者是typedef     map<string,   int>   MY_MAP;   MY_MAP   my_Ma…
[题目大意] 给出一个字符串,求第k大的子串.(输入1表示子串可重复,0表示不可重复) [思路] 显然,k大子串是后缀自动机的经典题型,可以利用后缀自动机的性质来解决.对于字符串 [前铺1]"abcbc",我们可以画出它的后缀自动机,如下图: Pre树类似于AC自动机中的fail树,即将pre方向形成一棵树.对于上图,它的pre树如下: [前铺2]考虑字符串s的任意非空子串t.我们称终点集合right(t)为:s中所有是t出现位置终点的集合.例如:对于字符串ATCGTCGT来说,所有的…
[题目大意] 求一个循环数列的最小表示法. [思路] 把原创复制一遍放在后面,建立SAM,从s按字典序开始跑长度L即可. 板子来源(作者见连接内):…
长长的消息 时间限制: 4000MS   内存限制: 131072K 提交总数: 32393   接受: 13079 案件时间限制: 1000MS 描述 小猫在拜特兰的首府物理专业.最近有一个不幸的消息传来,他的母亲生病了.担心在火车票上花费太多(拜特兰是一个如此大的国家,他不得不在火车上花费16个小时到家乡),他决定只和母亲发短信.  小猫生活在一个非常富有的家庭,所以他经常到移动服务中心去查看他在短信上花了多少钱.昨天,服务中心的电脑坏了,打印了两条很长的信息.很快就发现了这只聪明的小猫: …
题意 求出多个串的最长公共子串. 分析 刚学SAM想做这个题的话最好先去做一下那道codevs3160.求两个串的LCS应该怎么求?把一个串s1建自动机,然后跑另一个串s2,然后找出s2每个前缀的最长公共后缀.那么多个的时候,我们也用这种类似的方法,但是我们求最长公共后缀的时候要求第一个串的.我们把其中一个串建SAM,然后把其他的串都在上面跑,维护两个值,Max[u]和Min[u].自动机中每个状态u的Right存的是结尾集合.那么对于一个字符串,我们可以求出他和自动机中每个状态的最长公共后缀.…
做得心 力 憔 悴 Description 你有一个字符串S,一开始为空串,要求支持两种操作 在S后面加入字母C 删除S最后一个字母 问每次操作后S有多少个两两不同的连续子串 Input 一行一个字符串Q,表示对S的操作 如果第i个字母是小写字母c,表示第一种加字母c的操作 如果为-表示删除操作,保证所有删除操作前S都非空 |Q|<=10^5 Output 输出|Q|行,第i行表示i个操作之后S内有多少个不同子串 题目分析 陈老师神题x2,暂时只会做法一. 做法一:暴力回退 还是自己菜啊……这么…
网上有篇题解写的是线段树合并维护求值? 题目描述 有一个只包含小写字母,长度为 $n$ 的字符串 $S$ .有一些字母是好的,剩下的是坏的. 定义一个子串 $S_{l\ldots r}$是好的,当且仅当这个子串包含不超过 $k$ 个坏的字母. 求有多少个不同的满足以下要求的字符串 $T$ : $T$ 作为 $S$ 的子串出现过. 存在一个 $T$ 出现的位置 $[l,r]$ ,满足 $S_{l\ldots r}$​ 是好的. 输入格式 第一行有一个字符串 $S$ . 第二行有一个字符串 $B$…
对第一个串建SAM,把剩下的串在上面跑,每次跑一个串的时候在SAM的端点上记录匹配到这的最大长度,然后对这些串跑的结果取min,然后从这些节点的min中取max就是答案 注意在一个点更新后它的祖先也会被更新,需要最后按拓扑序向上更新一边 其实二分+hash就行 #include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=10005; int n,m,ch[N…