POJ3080 POJ3450Corporate Identity(广义后缀自动机||后缀数组||KMP)
Beside other services, ACM helps companies to clearly state their “corporate identity”, which includes company logo but also other signs, like trademarks. One of such companies is Internet Building Masters (IBM), which has recently asked ACM for a help with their new identity. IBM do not want to change their existing logos and trademarks completely, because their customers are used to the old ones. Therefore, ACM will only change existing trademarks instead of creating new ones.
After several other proposals, it was decided to take all existing trademarks and find the longest common sequence of letters that is contained in all of them. This sequence will be graphically emphasized to form a new logo. Then, the old trademarks may still be used while showing the new identity.
Your task is to find such a sequence.
Input
The input contains several tasks. Each task begins with a line containing a positive integer N, the number of trademarks (2 ≤ N ≤ 4000). The number is followed by N lines, each containing one trademark. Trademarks will be composed only from lowercase letters, the length of each trademark will be at least 1 and at most 200 characters.
After the last trademark, the next task begins. The last task is followed by a line containing zero.
Output
For each task, output a single line containing the longest string contained as a substring in all trademarks. If there are several strings of the same length, print the one that is lexicographically smallest. If there is no such non-empty string, output the words “IDENTITY LOST” instead.
Sample Input
3
aabbaabb
abbababb
bbbbbabb
2
xyz
abc
0
Sample Output
abb
IDENTITY LOST
题意:
求n个串的最长公共字串,如果有多个,输出最小字典序的一个。
思路:
KMP||后缀数组||广义后缀自动机,不说了,上高数课了。代码比较暴力。下课了再试一试优化。
对比:
后缀数组SA已经排序了,最小字典序好找。而后缀自动机则需要像字典树一样搜索。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<memory>
#include<cmath>
using namespace std;
int n,len,ans,Max,now;
const int maxn=;
char s[],cap[];
struct SAM
{
int ch[maxn][],fa[maxn],maxlen[maxn],Last,sz;
int root,nxt[maxn],size[maxn];bool Flag;
void init()
{
sz=;Flag=false;
root=++sz;
memset(size,,sizeof(size));
memset(ch[],,sizeof(ch[]));
memset(nxt,,sizeof(nxt));
}
void add(int x)
{
int np=++sz,p=Last;Last=np;
memset(ch[np],,sizeof(ch[np]));
maxlen[np]=maxlen[p]+;
while(p&&!ch[p][x]) ch[p][x]=np,p=fa[p];
if(!p) fa[np]=;
else {
int q=ch[p][x];
if(maxlen[p]+==maxlen[q]) fa[np]=q;
else {
int nq=++sz;
memcpy(ch[nq],ch[q],sizeof(ch[q]));size[nq]=size[q]; nxt[nq]=nxt[q];
maxlen[nq]=maxlen[p]+;
fa[nq]=fa[q];
fa[q]=fa[np]=nq;
while(p&&ch[p][x]==q) ch[p][x]=nq,p=fa[p];
}
}
for(;np;np=fa[np])
if(nxt[np]!=now) {
size[np]++;
nxt[np]=now;
}else break;
}
/* void dfs(int x,int d){//输出
if(Flag||d>n) return;
if(d==n){ puts(cap); Flag=true; return; }
for(int i=0;i<26;i++)
if(ch[x][i]&&size[ch[x][i]]==n){ cap[d]=i+'a'; dfs(ch[x][i],d+1); cap[d]=0; }
}*/
void dfs(int x,int d){//输出
if(d!=maxlen[x]||d>ans||Flag) return;
if(maxlen[x]==ans&&size[x]>=n) { puts(cap); Flag=true; return; }
for(int i=;i<;++i)
if(ch[x][i]){ cap[d]=i+'a'; dfs(ch[x][i],d+); cap[d]=; }
}
};
SAM Sam;
int main()
{
while(~scanf("%d",&n)&&n){
Sam.init();
for(int i=;i<=n;i++) {
scanf("%s",s+);
Sam.Last=Sam.root;
len=strlen(s+);
now=i;
for(int j=;j<=len;j++) Sam.add(s[j]-'a');
}
ans=;
for(int i=;i<=Sam.sz;i++)
if(Sam.size[i]==n&&Sam.maxlen[i]>ans) ans=Sam.maxlen[i];
if(ans) Sam.dfs(,);
else printf("IDENTITY LOST\n");
}
return ;
}
POJ3080 POJ3450Corporate Identity(广义后缀自动机||后缀数组||KMP)的更多相关文章
- poj 1743 Musical Theme 后缀自动机/后缀数组/后缀树
题目大意 直接用了hzwer的题意 题意:有N(1 <= N <=20000)个音符的序列来表示一首乐曲,每个音符都是1..88范围内的整数,现在要找一个重复的主题."主题&qu ...
- [模板] 后缀自动机&&后缀树
后缀自动机 后缀自动机是一种确定性有限状态自动机, 它可以接收字符串\(s\)的所有后缀. 构造, 性质 翻译自毛子俄罗斯神仙的博客, 讲的很好 后缀自动机详解 - DZYO的博客 - CSDN博客 ...
- UVA - 11107 Life Forms (广义后缀自动机+后缀树/后缀数组+尺取)
题意:给你n个字符串,求出在超过一半的字符串中出现的所有子串中最长的子串,按字典序输出. 这道题算是我的一个黑历史了吧,以前我的做法是对这n个字符串建广义后缀自动机,然后在自动机上dfs,交上去AC了 ...
- 回文树&后缀自动机&后缀数组
KMP,扩展KMP和Manacher就不写了,感觉没多大意思. 之前感觉后缀自动机简直可以解决一切,所以不怎么写后缀数组. 马拉车主要是通过对称中心解决问题,有的时候要通过回文串的边界解决问题 ...
- bzoj 3277: 串 & bzoj 3473: 字符串【后缀自动机||后缀数组】
建一个广义后缀自动机(每加完一个串都返回root),在parent树上dpsum记录合法长度,打着时间戳往上跳,最后每个串在自动机上跑一变统计答案即可. 后缀数组理解起来可能方便一点,但是难写,就只说 ...
- BZOJ 3926: [Zjoi2015]诸神眷顾的幻想乡 广义后缀自动机 后缀自动机 字符串
https://www.lydsy.com/JudgeOnline/problem.php?id=3926 广义后缀自动机是一种可以处理好多字符串的一种数据结构(不像后缀自动机只有处理一到两种的时候比 ...
- SPOJ705 Distinct Substrings (后缀自动机&后缀数组)
Given a string, we need to find the total number of its distinct substrings. Input T- number of test ...
- SPOJ SUBLEX - Lexicographical Substring Search 后缀自动机 / 后缀数组
SUBLEX - Lexicographical Substring Search Little Daniel loves to play with strings! He always finds ...
- 康复计划#1 再探后缀自动机&后缀树
本篇口胡写给我自己这样的东西都忘光的残废选手 以及那些刚学SAM,看了其他的一些东西并且没有完全懵逼的人 (初学者还是先去看有图的教程吧,虽然我的口胡没那么好懂,但是我觉得一些细节还是讲清楚了的) 大 ...
随机推荐
- Pell方程(求形如x*x-d*y*y=1的通解。)
佩尔方程x*x-d*y*y=1,当d不为完全平方数时,有无数个解,并且知道一个解可以推其他解. 如果d为完全平方数时,可知佩尔方程无解. 假设(x0,y0)是最小正整数解. 则: xn=xn-1*x0 ...
- GridView 显示行号 设置行号列的宽度
/// <summary> /// GridView 显示行号 设置行号列的宽度 /// </summary> /// <param name="gv" ...
- Powerdesigner Name与Comment的互相转换
使用说明: 在[Tools]-[Execute Commands]-[Edit/Run Script] 下.输入下面你要选择的语句即可: 1.Name填充Comment '把pd中那么name想自动添 ...
- spring boot数据库操作汇总
1 关于orm orm即object relational mapping,对象关系映射,即将数据库中的表映射成对象. 常用的orm有以下: mybatis spring jdbc template ...
- 【python】-- GIL锁、线程锁(互斥锁)、递归锁(RLock)
GIL锁 计算机有4核,代表着同一时间,可以干4个任务.如果单核cpu的话,我启动10个线程,我看上去也是并发的,因为是执行了上下文的切换,让看上去是并发的.但是单核永远肯定时串行的,它肯定是串行的, ...
- Python菜鸟之路:Python基础-内置函数补充
常用内置函数及用法: 1. callable() def callable(i_e_, some_kind_of_function): # real signature unknown; restor ...
- Java编程中的一些常见问题汇总
转载自 http://macrochen.iteye.com/blog/1393502 每天在写Java程序,其实里面有一些细节大家可能没怎么注意,这不,有人总结了一个我们编程中常见的问题.虽然一般 ...
- vMware存储:SAN配置基础
VMware存储不仅仅是将LUN映射给物理服务器这么简单.VMware vSphere允许系统管理员在一个物理机上创建多个虚拟机. 潜在的hypervisor和vSphere ESXi,能够使gues ...
- Java基础教程:多线程基础(1)——基础操作
Java:多线程基础(1) 实现多线程的两种方式 1.继承Thread类 public class myThread extends Thread { /** * 继承Thread类,重写RUN方法. ...
- UI组件之Label
Use Core Data 接口,链接数据库 Portrait 肖像模式 LandScape(Left, Right) 风景模式 1.程序启动后,从main接口进入, main函数会调用UIAppli ...