spoj 1812 LCS2(SAM+DP)
【题目链接】
http://www.spoj.com/problems/LCS2/en/
【题意】
求若干个串的最长公共子串。
【思路】
SAM+DP
先拿个串建个SAM,然后用后面的串匹配,每次将所有的匹配长度记录在状态上取min,然后对所有状态取max即答案。
需要更新fa,因为fa[p]一定比p更优,但匹配的时候可能只更新了p而没有更新fa[p],所以还需要递推一边。
注意mn[p]初始化为l[p]
【代码】
#include<cstdio>
#include<cstring>
using namespace std; const int N = *1e5+; char s[N];
int sz,last,root,l[N],ch[N][],fa[N],mn[N],mx[N];
int b[N],cnt[N];
void add(int x) {
int c=s[x]-'a';
int p=last,np=++sz; last=np;
l[np]=mn[np]=x+;
for(;p&&!ch[p][c];p=fa[p]) ch[p][c]=np;
if(!p) fa[np]=root;
else {
int q=ch[p][c];
if(l[p]+==l[q]) fa[np]=q;
else {
int nq=++sz; l[nq]=mn[nq]=l[p]+;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
fa[nq]=fa[q];
fa[np]=fa[q]=nq;
for(;ch[p][c]==q;p=fa[p]) ch[p][c]=nq;
}
}
} int main() {
root=last=++sz;
scanf("%s",s);
int len=strlen(s);
for(int i=;i<len;i++) add(i);
for(int i=;i<=sz;i++) cnt[l[i]]++;
for(int i=;i<=len;i++) cnt[i]+=cnt[i-];
for(int i=;i<=sz;i++) b[cnt[l[i]]--]=i;
while(scanf("%s",s)==) {
int p=root; len=;
for(int i=;s[i];i++) {
int c=s[i]-'a';
if(ch[p][c]) { len++; p=ch[p][c]; }
else {
while(p&&!ch[p][c]) p=fa[p];
if(!p) { len=; p=root; }
else { len=l[p]+; p=ch[p][c]; }
}
if(len>mx[p]) mx[p]=len;
}
for(int i=sz;i;i--) {
p=b[i];
if(mx[p]<mn[p]) mn[p]=mx[p];
if(fa[p] && mx[fa[p]]<mx[p]) mx[fa[p]]=mx[p];
mx[p]=;
}
}
int ans=;
for(int i=;i<=sz;i++)
if(mn[i]>ans) ans=mn[i];
printf("%d",ans);
return ;
}
spoj 1812 LCS2(SAM+DP)的更多相关文章
- CF1120 C. Compress String(SAM+DP)
有方程dp[i]=min(dp[i-1]+A,dp[j]+B):如果s[j+1,i]在s[i,j]中出现,所以我们就是要知道每个子串在s出现的第一个位置,这个可以hash实现或者sam,或者kmp实现 ...
- [HAOI2016]找相同字符(SAM+DP)
感觉很水. 因为SAM上一个点的子树大小代表这个点所表示子串的出现次数. 建出广义后缀自动机之后.在\(parent\)树上跑\(DP\),维护\(size[i][1]\),和\(size[i][0] ...
- SPOJ 1812 LCS2 [后缀自动机 DP]
题意: 求多个串<=10的最长连续子串 一个串建SAM,然后其他串在上面走 每个状态记录所有串在这个状态的公共子串的最小值 一个串在上面走的时候记录与每个状态公共子串的最大值,注意出现次数向父亲 ...
- 【SPOJ】Substrings(后缀自动机)
[SPOJ]Substrings(后缀自动机) 题面 Vjudge 题意:给定一个长度为\(len\)的串,求出长度为1~len的子串中,出现最多的出现了多少次 题解 出现次数很好处理,就是\(rig ...
- spoj 1812 LCS2 - Longest Common Substring II (后缀自己主动机)
spoj 1812 LCS2 - Longest Common Substring II 题意: 给出最多n个字符串A[1], ..., A[n], 求这n个字符串的最长公共子串. 限制: 1 < ...
- ACdreamOJ 1154 Lowbit Sum (数字dp)
ACdreamOJ 1154 Lowbit Sum (数位dp) ACM 题目地址:pid=1154" target="_blank" style="color ...
- 「SDOI2016」储能表(数位dp)
「SDOI2016」储能表(数位dp) 神仙数位 \(dp\) 系列 可能我做题做得少 \(QAQ\) \(f[i][0/1][0/1][0/1]\) 表示第 \(i\) 位 \(n\) 是否到达上界 ...
- 【HDU1693】Eat the Trees(插头dp)
[HDU1693]Eat the Trees(插头dp) 题面 HDU Vjudge 大概就是网格图上有些点不能走,现在要找到若干条不相交的哈密顿回路使得所有格子都恰好被走过一遍. 题解 这题的弱化版 ...
- 【BZOJ1814】Ural 1519 Formula 1 (插头dp)
[BZOJ1814]Ural 1519 Formula 1 (插头dp) 题面 BZOJ Vjudge 题解 戳这里 上面那个链接里面写的非常好啦. 然后说几个点吧. 首先是关于为什么只需要考虑三进制 ...
随机推荐
- DELPHI关于文件的操作
caption:= ExtractFileExt(‘带路径,带扩展名的文件名’);//返回的就是扩展名 caption:= ChangeFileExt(ExtractFileName(‘带路径,带扩 ...
- Mac OSX 安装Python的paramiko模块经验总结
一.简单介绍 最近需要用Python模拟登录远程服务器并自动执行一些代码,需要安装一个叫paramiko的模块. paramiko官方介绍遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接 ...
- mvc框架下,怎样用cookie实现下次自动登录
登录时有个下次自动登录的checkBox.点了它下次就可以自动登录了 具体流程我都晓得,就是细节的地方有些搞不定.我只要解决3个问题: (1)登录时如果点了checkbox,则在本机产生一个cooki ...
- 【filter】springmvc web.xml
1.filter用于拦截用户请求,在服务器作出响应前,可以在拦截后修改request和response,这样实现很多开发者想得到的功能. 2.filter实现 ×编写一个继承Filter接口的类 ×在 ...
- 中国.net域名网站的“前世今生”,那些年的光辉
1987年9月的一天,中国的第一封电子邮件成功发出,邮件的内容大致是“跨越长城,走向世界”,在当时,没有人会想到十年后中国的互联网开始萌芽,并发展成今天的繁荣.1994年,“巴黎统筹委员会”的解散消除 ...
- 用easyui动态创建一个对话框
function randomString(len) { len = len || 32; var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxy ...
- hdu 4267
一个很不错的题: 刚刚看到这个题目就感觉要用线段树或者树状数组,但是有感觉有点不同: 敲了一发简单的线段树之后果断的T了: 网上一搜题解,发现要用55颗线段树或者树状数组: 一共有k种树,然后每种树根 ...
- 静态分析安全测试(SAST)优缺点探析
静态分析安全测试(SAST)是指不运行被测程序本身,仅通过分析或者检查源程序的语法.结构.过程.接口等来检查程序的正确性,那么采用静分析安全测试的方法有什么优缺点呢,且让小编给你说道说道. 许多公司都 ...
- 如何避免远程循环执行SSH时,到第一条之后就退出
RT 今天遇到的小问题,记录下来. 据说关键是加 < /dev/null 我也是看网上别人说的,测试成功. #!/bin/bash while read line do echo $line ...
- UVA 658 It's not a Bug, it's a Feature!
这个题目巧妙之处在于用二进制的每个位1,0分别表示bug的有无,以及实施补丁对相应bug的要求以及实施后的对bug的影响. 软件bug的状态:1表示相应bug仍然存在,0表示已经修复.这样可以将软件的 ...