POJ2774 Long Long Message 【SAM】
POJ2774 Long Long Message
找两个串的最长公共字串
对其中一个串\(s\)建\(SAM\),然后我们如何找到最长公共字串,办法就是枚举\(t\)串所有的前缀,然后找各个前缀的最长能和\(s\)串匹配的后缀。
如果一个个跑需要\(O(n^2)\),\(SAM\)可以来保存之前匹配的状态,假设现在匹配的状态是\(u\),匹配到的最长后缀长度为\(l\),那么现在考虑在当前状态后面加上一个字符,也就是成为\(t\)串一个新的前缀,那么最大能匹配的必然是在上一次匹配到的最长串的基础上去匹配,所以我们可以不断判断\(u\)这个状态是否有连向新加入的字符的边,如果有的话,更新\(u,l \Rightarrow u = ch[u][c]; l+=1\),如果没有的话,就要跑当前状态的后缀链接,找到最长的\(endpos\)不同的之前匹配串的一个后缀,然后更新\(u,l \Rightarrow u = link[u]; l = len[u]\),直到遇到有连边的状态或者到了初始点。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<string>
#include<algorithm>
#include<stack>
using namespace std;
void ____(){ ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); }
const int MAXN = 2e5+7;
char s[MAXN];
struct SAM{
int len[MAXN],link[MAXN],ch[MAXN][26],last,tot;
void init(){ link[tot = last = 0] = -1; memset(ch[0],0,sizeof(ch[0])); }
void extend(int c){
int np = ++tot; memset(ch[tot],0,sizeof(ch[tot]));
int p = last; len[np] = len[last] + 1;
while(p!=-1 and !ch[p][c]){
ch[p][c] = np;
p = link[p];
}
if(p==-1) link[np] = 0;
else{
int q = ch[p][c];
if(len[p]+1==len[q]) link[np] = q;
else{
int clone = ++tot;
len[clone] = len[p] + 1;
link[clone] = link[q];
for(int i = 0; i < 26; i++) ch[clone][i] = ch[q][i];
link[np] = link[q] = clone;
while(p!=-1 and ch[p][c]==q){
ch[p][c] = clone;
p = link[p];
}
}
}
last = np;
}
int lcs(char *str){
int ret = 0, u = 0, l = 0, n = strlen(str);
for(int i = 0; i < n; i++){
int c = str[i] - 'a';
while(u and !ch[u][c]){
u = link[u];
l = len[u];
}
if(ch[u][c]) u = ch[u][c], l++;
ret = max(ret,l);
}
return ret;
}
}sam;
int main(){
while(scanf("%s",s)!=EOF){
sam.init(); int n = strlen(s);
for(int i = 0; i < n; i++) sam.extend(s[i]-'a');
scanf("%s",s);
printf("%d\n",sam.lcs(s));
}
return 0;
}
POJ2774 Long Long Message 【SAM】的更多相关文章
- 【SAM】codevs3160-最长公共子串
[题目大意] 求两个字符串的最长公共子串. [思路] 对第一个字符串建立后缀自动机,第二个字符串去匹配.cnt记录当前最长公共子串的长度,而ret记录答案. p代表位置指针,初始在rt位置. 对于第二 ...
- 【SAM】BZOJ2882-工艺
[题目大意] 求一个循环数列的最小表示法. [思路] 最小表示法的正解:★ SAM乱搞,和前面的POJ那道一样.然而MLE了,当作学习一下map的用法^ ^ map的使用方法(来源:☆) 一.map的 ...
- 【SAM】BZOJ3998-弦论
[题目大意] 给出一个字符串,求第k大的子串.(输入1表示子串可重复,0表示不可重复) [思路] 显然,k大子串是后缀自动机的经典题型,可以利用后缀自动机的性质来解决.对于字符串 [前铺1]" ...
- 【SAM】POJ1509-Glass Beads
[题目大意] 求一个循环数列的最小表示法. [思路] 把原创复制一遍放在后面,建立SAM,从s按字典序开始跑长度L即可. 板子来源(作者见连接内):
- POJ2774 Long Long Message 【后缀数组lcp】
长长的消息 时间限制: 4000MS 内存限制: 131072K 提交总数: 32393 接受: 13079 案件时间限制: 1000MS 描述 小猫在拜特兰的首府物理专业.最近有一个不幸的消 ...
- 【SPOJ - LCS2】Longest Common Substring II【SAM】
题意 求出多个串的最长公共子串. 分析 刚学SAM想做这个题的话最好先去做一下那道codevs3160.求两个串的LCS应该怎么求?把一个串s1建自动机,然后跑另一个串s2,然后找出s2每个前缀的最长 ...
- 【SAM】bzoj5084: hashit
做得心 力 憔 悴 Description 你有一个字符串S,一开始为空串,要求支持两种操作 在S后面加入字母C 删除S最后一个字母 问每次操作后S有多少个两两不同的连续子串 Input 一行一个字符 ...
- 【SAM】loj#6401. 字符串
网上有篇题解写的是线段树合并维护求值? 题目描述 有一个只包含小写字母,长度为 $n$ 的字符串 $S$ .有一些字母是好的,剩下的是坏的. 定义一个子串 $S_{l\ldots r}$是好的,当且仅 ...
- bzoj 2946: [Poi2000]公共串【SAM】
对第一个串建SAM,把剩下的串在上面跑,每次跑一个串的时候在SAM的端点上记录匹配到这的最大长度,然后对这些串跑的结果取min,然后从这些节点的min中取max就是答案 注意在一个点更新后它的祖先也会 ...
随机推荐
- sql查询速度慢分析及如何优化查询
原因分析后台数据库中数据过多,未做数据优化数据请求-解析-展示处理不当 网络问题提高数据库查询的速度方案SQL 查询速度慢的原因有很多,常见的有以下几种:1.没有索引或者没有用到索引(查询慢最常见的问 ...
- dubbo配置启动时检查
启动检查设置 Dubbo缺省会在启动时检查依赖的服务是否可用,不可用会抛出异常,阻止Spring初始化完成,默认check="true":是开启检查. 比如测试的时候,有些服务并不 ...
- jenkins 构建历史 显示版本号
0 jenkins 安装此插件: 此插件名为 " groovy postbuild " 1 效果图: 2 安装插件: 系统管理 --> 插件管理 --> 可选 ...
- SQLI-LABS复现通关
sql-lab 复现通关(深入学习) less-1 基于错误的单引号字符串 - 正常访问 127.0.0.1/?id=1 - 添加 ' 返回报错信息:You have an error in your ...
- innobackupex: Connecting to MySQL server with DSN 'dbi:mysql
[root@ma src]# innobackupex --user=root /root/backup --no-timestamp InnoDB Backup Utility v1.5.1-xtr ...
- SDUST数据结构 - chap9 排序
判断题: 选择题: 编程题: 7-1 排序: 输入样例: 11 4 981 10 -17 0 -20 29 50 8 43 -5 输出样例: -20 -17 -5 0 4 8 10 29 43 50 ...
- C# 请求被中止: 未能创建 SSL/TLS 安全通道。 设置SecurityProtocol无效
今天为了获取一张图片,用了一段代码: ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateV ...
- Kubernetes 升级过程记录:从 1.17.0 升级至最新版 1.20.2
本文记录的是将 kubernetes 集群从 1.17.0 升级至最新版 1.20.2 的实际操作步骤,由于 1.17.0 无法直接升级到 1.20.2,需要进行2次过滤升级,1.17.0 -> ...
- C++:标准I/O流
标准I/O对象:cin,cout,cerr,clog cout; //全局流对象 输出数据到显示器 cin; //cerr没有缓冲区 clog有缓冲区 cerr; //标准错误 输出数据到显示器 cl ...
- Python安装教程之anaconda篇
[导读]我们知道,Python的功能非常强大.那么对于迫切想学习Python的新手同学来说,第一件事情可能需要了解python是什么?能用来做什么?语法结构是怎样的?这些我们几句话很难介绍清楚,后续会 ...