You may have wondered why most extraterrestrial life forms resemble humans, differing by superficial traits such as height, colour, wrinkles, ears, eyebrows and the like. A few bear no human resemblance; these typically have geometric or amorphous shapes like cubes, oil slicks or clouds of dust.

The answer is given in the 146th episode of Star Trek - The Next Generation, titled The Chase. It turns out that in the vast majority of the quadrant's life forms ended up with a large fragment of common DNA.

Given the DNA sequences of several life forms represented as strings of letters, you are to find the longest substring that is shared by more than half of them.

Input

Standard input contains several test cases. Each test case begins with 1 ≤ n ≤ 100, the number of life forms. n lines follow; each contains a string of lower case letters representing the DNA sequence of a life form. Each DNA sequence contains at least one and not more than 1000 letters. A line containing 0 follows the last test case.

Output

For each test case, output the longest string or strings shared by more than half of the life forms. If there are many, output all of them in alphabetical order. If there is no solution with at least one letter, output "?". Leave an empty line between test cases.

Sample Input

3
abcdefg
bcdefgh
cdefghi
3
xxx
yyy
zzz
0

Sample Output

bcdefg
cdefgh ?

题意:

给定一些模板字符串,求一个最长公共字串,这个最长公共字串至少在一半以上的字符串里出现过。

思路:

把模板字符串都连接起来。二分长度,RMQ去验证。

(服了,网上找不到广义后缀自动机的资料。。。)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<memory>
#include<cmath>
#define maxn 350003
using namespace std;
int n,len,ans,Max,now;
char s[],cap[];
struct SAM
{
int ch[maxn][],fa[maxn],maxlen[maxn],Last,sz;
int root,nxt[maxn],size[maxn];
void init()
{
sz=;
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(d!=maxlen[x] || d>ans) return;
if(maxlen[x]==ans && size[x]>n){ puts(cap); 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');
}
Max=;ans=;n>>=;
for(int i=;i<=Sam.sz;i++)
if(Sam.size[i]>n&&Sam.maxlen[i]>ans) { Max=i;ans=Sam.maxlen[i];}
if(ans) Sam.dfs(,);
else puts("?");
puts("");
}
return ;
}

参考:http://blog.csdn.net/JacaJava/article/details/78678612?locationNum=6&fps=1

POJ3294Life Forms(广义后缀自动机)(后缀数组+二分+数状数组)的更多相关文章

  1. poj 1743 Musical Theme 后缀自动机/后缀数组/后缀树

    题目大意 直接用了hzwer的题意 题意:有N(1 <= N <=20000)个音符的序列来表示一首乐曲,每个音符都是1..88范围内的整数,现在要找一个重复的主题."主题&qu ...

  2. [模板] 后缀自动机&&后缀树

    后缀自动机 后缀自动机是一种确定性有限状态自动机, 它可以接收字符串\(s\)的所有后缀. 构造, 性质 翻译自毛子俄罗斯神仙的博客, 讲的很好 后缀自动机详解 - DZYO的博客 - CSDN博客 ...

  3. 【BZOJ-2527】Meteors 整体二分 + 树状数组

    2527: [Poi2011]Meteors Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 831  Solved: 306[Submit][Stat ...

  4. 【BZOJ3110】【整体二分+树状数组区间修改/线段树】K大数查询

    Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个位置到第b个位 ...

  5. BZOJ_3110_[Zjoi2013]K大数查询_整体二分+树状数组

    BZOJ_3110_[Zjoi2013]K大数查询_整体二分+树状数组 Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位 ...

  6. bzoj千题计划316:bzoj3173: [Tjoi2013]最长上升子序列(二分+树状数组)

    https://www.lydsy.com/JudgeOnline/problem.php?id=3173 插入的数是以递增的顺序插入的 这说明如果倒过来考虑,那么从最后一个插入的开始删除,不会对以某 ...

  7. 【bzoj3110】[Zjoi2013]K大数查询 整体二分+树状数组区间修改

    题目描述 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c.如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数 ...

  8. zoj-3963 Heap Partition(贪心+二分+树状数组)

    题目链接: Heap Partition Time Limit: 2 Seconds      Memory Limit: 65536 KB      Special Judge A sequence ...

  9. 【bzoj4009】[HNOI2015]接水果 DFS序+树上倍增+整体二分+树状数组

    题目描述 给出一棵n个点的树,给定m条路径,每条路径有一个权值.q次询问求一个路径包含的所有给定路径中权值第k小的. 输入 第一行三个数 n和P 和Q,表示树的大小和盘子的个数和水果的个数. 接下来n ...

随机推荐

  1. 【智力题】IO——行测、笔试、面试中遇到的

    昨天(05.23)下午去参加了明源软件的暑期实习宣讲+笔试,第一次听说这个行业,行业和笔试风格完全不一样啊,5道行测智力题+1个问答+ 斐波那契数列 + 洗牌算法(思想.流程图.代码),今年回来后线上 ...

  2. x^a=b(mod c)求解x在[0,c-1]上解的个数模板+原根求法

    /************************************* 求解x^a=b(mod c) x在[0,c-1]上解的个数模板 输入:1e9>=a,b>=1,1e9>= ...

  3. 【BZOJ1513】[POI2006]Tet-Tetris 3D 二维线段树

    [BZOJ1513][POI2006]Tet-Tetris 3D Description Task: Tetris 3D "Tetris" 游戏的作者决定做一个新的游戏, 一个三维 ...

  4. 九度OJ 1251:序列分割 (DFS)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:166 解决:34 题目描述: 一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值   比如{3,2,4,3,6} 可以分成{ ...

  5. 【网络与系统安全】关于SSL/TSL协议的分析

    前言 TSL协议的前身是由网景(Netscape)公司于1994年研发的安全套接字(Secure Socket Layer)协议.它建立在TCP协议栈的传输层,用于保护面向连接的TCP通信.实际TSL ...

  6. 使用apt-get 安装后的mysql 登录问题

    当使用apt-get安装mysql后,ubuntu会自动生成一个用户名和密码.所以在第一次登陆时会报如下错误 ERROR 1045 (28000): Access denied for user 'd ...

  7. 【WEB】高并发Web服务的演变-节约系统内存和CPU

    目前主流浏览器通常可以存在2-6个并发. 连接和请求,占据了服务器的大量CPU和内存等资源.在资源数目超过100+的网站页面中,使用更多的下载连接,非常有必要. 缓解“高并发”的压力的手段. 一. W ...

  8. JDK线程池的实现

    线程池 接口Executor 该接口只有一个方法,JDK解释如下 执行已提交的Runnable 任务的对象.此接口提供一种将任务提交与每个任务将如何运行的机制(包括线程使用的细节.调度等)分离开来的方 ...

  9. Data Structure Binary Tree: Populate Inorder Successor for all nodes

    http://www.geeksforgeeks.org/populate-inorder-successor-for-all-nodes/ #include <iostream> #in ...

  10. 《程序员代码面试指南》第二章 链表问题 删除中间节点和a/b处节点

    题目 例如 1-2-3-4 删除2,1-2-3-4-5 删除3 例如 a=1,b =2 java代码 /** * @Description:删除中间节点和a/b处节点 * @Author: lizho ...