刷题总结——spoj1812(后缀自动机+DP)
题目:
A string is finite sequence of characters over a non-empty finite set Σ.
In this problem, Σ is the set of lowercase letters.
Substring, also called factor, is a consecutive sequence of characters occurrences at least once in a string.
Now your task is simple, for two given strings, find the length of the longest common substring of them.
Here common substring means a substring of two or more strings.
Input
The input contains exactly two lines, each line consists of no more than 250000 lowercase letters, representing a string.
Output
The length of the longest common substring. If such string doesn't exist, print "0" instead.
Example
Input:
alsdfkjfjkdsal
fdjskalajfkdsla Output:
3
Notice: new testcases added
题解:
注:参照神犇hahalidaxin的题解.
SAM+DP
先拿个串建个SAM,然后用后面的串匹配,每次将所有的匹配长度记录在状态上取min,然后对所有状态取max即答案。
需要更新fa,因为fa[p]一定比p更优,但匹配的时候可能只更新了p而没有更新fa[p],所以还需要递推一边。
注意mn[p]初始化为l[p]
心得:
目前没什么好说的··dp和sam都不熟的情况下想做这道题真的很懵b····感觉没什么收获··以后再来看看吧···
代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<cctype>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int N=;
int pre[N],son[N][],step[N],last=,root=,tot=,minn[N],maxx[N];
int cnt[N],len,b[N];
char s[N];
struct suffix_auto
{
void extend(int ch)
{
int p=last,np=++tot;
minn[tot]=step[tot]=step[last]+;
for(;p&&!son[p][ch];p=pre[p]) son[p][ch]=np;
if(!p) pre[np]=root;
else
{
int q=son[p][ch];
if(step[q]!=step[p]+)
{
int nq=++tot;
minn[nq]=step[nq]=step[p]+;
memcpy(son[nq],son[q],sizeof(son[q]));
pre[nq]=pre[q];
pre[q]=pre[np]=nq;
for(;son[p][ch]==q;p=pre[p]) son[p][ch]=nq;
}
else
pre[np]=q;
}
last=np;
}
void build()
{
scanf("%s",s);
len=strlen(s);
for(int i=;i<len;i++)
extend(s[i]-'a');
}
}automa;
int main()
{
freopen("a.in","r",stdin);
automa.build();
for(int i=;i<=tot;i++) cnt[step[i]]++;
for(int i=;i<=len;i++) cnt[i]+=cnt[i-];
for(int i=;i<=tot;i++) b[cnt[step[i]]--]=i;
while(scanf("%s",s)==)
{
int len1=strlen(s);
int p=root,len=;
for(int i=;i<len1;i++)
{
int ch=s[i]-'a';
if(son[p][ch]) len++,p=son[p][ch];
else
{
while(p&&!son[p][ch]) p=pre[p];
if(!p) len=,p=root;
else
{
len=step[p]+;
p=son[p][ch];
}
}
if(maxx[p]<len) maxx[p]=len;
}
for(int i=tot;i;i--)
{
int j=b[i];
if(maxx[j]<minn[j]) minn[j]=maxx[j];
if(pre[p]&&maxx[pre[j]]<maxx[j]) maxx[pre[j]]=maxx[j];
maxx[j]=;
}
}
int ans=;
for(int i=;i<=tot;i++)
ans=max(ans,minn[i]);
cout<<ans<<endl;
return ;
}
刷题总结——spoj1812(后缀自动机+DP)的更多相关文章
- 【bzoj3998】[TJOI2015]弦论 后缀自动机+dp
题目描述 对于一个给定长度为N的字符串,求它的第K小子串是什么. 输入 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个.T=1则表示不同位置 ...
- 「刷题笔记」AC自动机
自动AC机 Keywords Research 板子题,同luoguP3808,不过是多测. 然后多测不清空,\(MLE\)两行泪. 板子放一下 #include<bits/stdc++.h&g ...
- bzoj 2806: [Ctsc2012]Cheat 后缀自动机DP
2806: [Ctsc2012]Cheat Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 583 Solved: 330[Submit][Statu ...
- HDU - 6583 Typewriter (后缀自动机+dp)
题目链接 题意:你要打印一段字符串,往尾部添加一个字符需要花费p元,复制一段字符到尾部需要花费q元,求打印完全部字符的最小花费. 一开始想的贪心,后来发现忘了考虑p<q的情况了,还纳闷怎么不对. ...
- BZOJ4032[HEOI2015]最短不公共子串——序列自动机+后缀自动机+DP+贪心
题目描述 在虐各种最长公共子串.子序列的题虐的不耐烦了之后,你决定反其道而行之. 一个串的“子串”指的是它的连续的一段,例如bcd是abcdef的子串,但bde不是. 一个串的“子序列”指的是它的可以 ...
- fjwc2019 D1T2 原样输出(后缀自动机+dp)
#179. 「2019冬令营提高组」原样输出 暴力对每个串建后缀自动机,然后暴力枚举每个自动机的子串.可以拿到部分分. 然鹅我们可以把每个后缀自动机连起来. 我们知道,后缀自动机是用最少的点(空间)表 ...
- 【BZOJ3238】差异【后缀自动机+dp】
题意 分析 这个题目还是很优秀的.sigma(len(Ti)+len(Tj))的值是一定的=n*(n+1)*(n-1)/2.那么关键就是求任意两个后缀的lcp的和了. 我们怎么求两个后缀的lcp?如果 ...
- 【SPOJ - SUBLEX】Lexicographical Substring Search 【后缀自动机+dp】
题意 给出一个字符串和q个询问,每个询问给出一个整数k,输出第k大得子串. 分析 建后缀自动机,利用匹配边来解决.设d[v]为从状态v开始有多少不同的路径.这个显然是可以递推出来的.然后对于每个询问, ...
- 【SPOJ -NSUBSTR】Substrings 【后缀自动机+dp】
题意 给出一个字符串,要你找出所有长度的子串分别的最多出现次数. 分析 我们建出后缀自动机,然后预处理出每个状态的cnt,cnt[u]指的是u这个状态的right集合大小.我们设f[len]为长度为l ...
- 【BZOJ 4199】[Noi2015]品酒大会 后缀自动机+DP
题意 两个长度为$r$的子串相等称为$r$相似,两个$r$相似的权值等于子串开头位置权值乘积,给定字符串和每个位置权值,求$r$相似子串数量和最大权值乘积 对反串建立后缀自动机得到后缀树,后缀树上两个 ...
随机推荐
- Windows系统下Android开发环境搭建
“工具善其事,必先利其器”.要想学好Android,搭建好Android开发环境是一个良好的开端. Windows系统下Android开发环境主要有4个大的步骤.分别是: 1.JDK的安装 2.ecl ...
- SQL问题:未启用当前数据库的 SQL Server Service Broker
数据库分离后,附加回到数据库,然后在程序中打开调用数据库的页面,出现如下问题:“未启用当前数据库的 SQL Server Service Broker,因此查询通知不受支持.如果希望使用通知,请为此数 ...
- Higher level thinking
「Higher level thinking」-- 出自 Ray Dalio 的<Principles>(PDF 原文:Principles by Ray Dalio) Higher le ...
- 用valgrind检查内存问题
Valgrind Valgrind作为一个免费且优秀的工具包,平时大部分人可能都是使用valgrind检测内存问题,如内存泄露,越界等. Valgrind工具包包含多个工具,如Memcheck,Cac ...
- Open Cascade:拓扑类型(Topo_DS)之间类型转换
TopoDS_Edge aEdge = TopoDS::Edge(myAISShape->Shape()); TopoDS_Wire S1_wire = static_cast(S1); // ...
- Caused by: java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'userController' method
在使用SpringMVC的时候遇到了这个问题 问题原因: 在指定方法所对应的url地址的时候重复了, 也就是@RequestMapping("url")中, 两个方法使用了同一个 ...
- 多线程下载命令--axel
axel是轻量级多线程下载工具,对比传统下载工具curl和wget,下载速度上提升不少 centos安装如下 yum install -y axel 命令行用法 axel [option] url1 ...
- 几句话总结一个算法之RNN、LSTM和GRU
RNN 一般神经网络隐层的计算是h=g(w * x),其中g是激活函数,相比于一般神经网络,RNN需要考虑之前序列的信息,因此它的隐藏h的计算除了当前输入还要考虑上一个状态的隐藏,h=g(w*x+w' ...
- base64类
public class Base64{ /** * how we separate lines, e.g. \n, \r\n, \r etc. */ private String lineSepar ...
- ios多线程之GCD
介绍: Grand Central Dispatch 简称(GCD)是苹果公司开发的技术,以优化的应用程序支持多核心处理器和其他的对称多处理系统的系统.这建立在任务并行执行的线程池模式的基础上的.它首 ...