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就是答案 注意在一个点更新后它的祖先也会 ...
随机推荐
- JAVA开发手册-Markdown
前言 前 言 <Java 开发手册>是技术团队的集体智慧结晶和经验总结,经历了多次大规模一线实战的检验及不断完善.现代软件行业的高速发展对开发者的综合素质要求越来越高,因为不仅是编程知识点 ...
- [从源码学设计]蚂蚁金服SOFARegistry之续约和驱逐
[从源码学设计]蚂蚁金服SOFARegistry之续约和驱逐 目录 [从源码学设计]蚂蚁金服SOFARegistry之续约和驱逐 0x00 摘要 0x01 业务范畴 1.1 失效剔除 1.2 服务续约 ...
- 【Java】面向对象 - 封装
继承 封装 多态 重新搞一波 复习巩固 简单记录 慕课网 imooc Java 零基础入门-Java面向对象-Java封装 封装 封装是什么? 将类的某些信息隐藏在类内部,不允许外部程序直接访问 通过 ...
- Can't locate Time/HiRes.pm in @INC (@INC contains
Can't locate Time/HiRes.pm in @INC (@INC contains: /usr/local/lib/perl5 /usr/local/share/perl5 /usr/ ...
- 【Linux】将ens33修改为eth0 网卡方法
1.编辑 grub 配置文件 vim /etc/sysconfig/grub # 其实是/etc/default/grub的软连接 # 为GRUB_CMDLINE_LINUX变量增加2个参数,添加的内 ...
- CentOS6.8安装及各种坑
实现目的:用U盘安装CentOS 6.2 32位系统 所需工具: 一.UltraISO(用来制作U盘启动) 下载地址:http://www.newhua.com/soft/614.htm 二.Cent ...
- MCU的心脏-晶振
晶振是石英晶体谐振器(quartzcrystal oscillator)的简称,它被称为电路系统的心脏,它为整个系统提供"心跳".中央处理器(CPU)一切指令的执行都是建立在这个& ...
- LeetCode589. N叉树的前序遍历
题目 法一.递归 1 class Solution { 2 public: 3 vector<int>ans; 4 void dfs(Node* root){ 5 if(root!=NUL ...
- 关于BAPI_TRANSACTION_COMMIT一点说明
我们调用bapi做了相关的业务操作后,通常都要在后面调用 BAPI_TRANSACTION_COMMIT来提交所做得更改 然而,有时候,在程序中需要调用多个不同的BAPI实现不同的功能,那么这个时候就 ...
- webapi Swagger 配置 services.BuildServiceProvider() 报警 ASP0000 问题处理
问题起源 网上的常见配置 Swagger 配置 在Startup类的 ConfigureServices 使用 services.BuildServiceProvider() ,其中有段代码如下: v ...