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 题解 戳这里 上面那个链接里面写的非常好啦. 然后说几个点吧. 首先是关于为什么只需要考虑三进制 ...
随机推荐
- VC++添加工具栏
VC添加工具栏 方法一:添加ICON图标 1. 新建一个基于对话框的项目:Test 2. 在类CTestDlg中, 添加两个变量: CToolBarCtrl m_ToolBar1; CImageLis ...
- 我写了个教程《一步步教你把ubuntu安装到U盘》
一步步教你把ubuntu安装到U盘 作者 Val 2452013147@qq.com 原因: 由于某些原因(学生党),需要把ubuntu安装到U盘到处走,百度了一下,教程都不是很好,要么很复杂,要么不 ...
- uvision4 ide已停止工作
情景描述: 笔者安装了新系统WIN8.1,装上了MDKV4.72.MDK编译程序可以正常工作,可是只要当我“下载程序”或者“调试程序”的时候就提示“uvision4 ide已停止工作”,迫不得已只能关 ...
- iOS runloop 资源汇总-b
RunLoop 是 iOS 和 OSX 开发中非常基础的一个概念,这篇文章将从 CFRunLoop 的源码入手,介绍 RunLoop 的概念以及底层实现原理.之后会介绍一下在 iOS 中,苹果是如何利 ...
- RPM是RedHat Package Manager(RedHat软件包管理工具)
RPM是RedHat Package Manager(RedHat软件包管理工具)类似Windows里面的“添加/删除程序” rpm 执行安装包二进制包(Binary)以及源代码包(Source)两种 ...
- <django中render_to_response的可选参数和使用方法>
在django官方文档中有比较详细的介绍,在此我按照自己的理解适当的阐述一下: return render_to_response(①'my_template.html', ②my_data_dict ...
- 如何使用 Zend Expressive 建立 NASA 图片库?
在本文中,我们将借助 NASA 天文图库 API,使用 Zend Expressive 建立图片库.最后的结果将显示在 AstroSplash 网站,该网站是为了文本特意搭建的.本文系 OneAPM ...
- Linux配置系统
配置架构: 三元素: 配置文件, 环境变量, 命令行选项 三级别: 系统级,用户级,程序级 应用: 调用时可能发生变化的配置信息,使用命令行选项:改动很少但确实应该由各个用户自己控制的配置信息,使用用 ...
- Percona Xtrabackup备份mysql全库及指定数据库(完整备份与增量备份)
原文地址:http://www.tuicool.com/articles/RZRnq2 Xtrabackup简介 Percona XtraBackup是开源免费的MySQL数据库热备份软件,它能对In ...
- 查看java的.class文件的方法
在不通过eclipse等IDE安装反编译插件的情况下查看java的.class文件的方法:可以通过下载jd-gui class文件查看工具进行查看.如附件的“jd-gui.exe”程序. 1. 从网上 ...