Life Forms
Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 12688   Accepted: 3552

Description

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 ? 二分长度把height分组,同组在不同的n/2个串里就是答案,只需记录该组中任意一个后缀的起点
SA尤其要注意开够数组,免得连接串的时候出错
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MN 200003
using namespace std; int n,m,nm,nnm;
char s1[MN];
int s[MN],a[MN];
int v[MN],sa[MN],q[MN],rank[MN],h[MN],mmh=,len,nu[MN],st[MN];
bool w[];
inline void gr(int x){
rank[sa[]]=;
for (int i=;i<=n;i++) rank[sa[i]]=(s[sa[i]]==s[sa[i-]]&&s[sa[i]+x]==s[sa[i-]+x])?rank[sa[i-]]:rank[sa[i-]]+;
for (int i=;i<=n;i++) s[i]=rank[i];
}
inline void gv(){memset(v,,sizeof(v));for (int i=;i<=n;i++) v[s[i]]++;for (int i=;i<=2e5;i++)v[i]+=v[i-];}
inline void gsa(){
gv();for (int i=n;i>=;i--) sa[v[s[i]]--]=i;gr();
for (int i=;i<n;i<<=){
gv();for (int j=n;j>=;j--) if (sa[j]>i) q[v[s[sa[j]-i]]--]=sa[j]-i;
for (int j=n-i+;j<=n;j++) q[v[s[j]]--]=j;
for (int j=;j<=n;j++) sa[j]=q[j];gr(i);
if (rank[sa[n]]==n) return;
}
}
inline void gh(){for (int i=,k=,j;i<=n;h[rank[i++]]=k) for (k?k--:,j=sa[rank[i]-];a[i+k]==a[j+k]&&i+k<=n&&j+k<=n;k++);}
int main(){
scanf("%d",&n);
while(n){
nm=;
for (int i=;i<=n;i++){
scanf("%s",s1);
m=strlen(s1);
for (int j=;j<m;j++) a[++nm]=s1[j]-'a',nu[nm]=i;a[++nm]=+i;
}
nnm=n;
n=nm;
for (int i=;i<=nm;i++) s[i]=a[i];
gsa();gh();
int l=,r=n,mid,bo=,i,j,k,mmh,pos;
while(l<r){
mid=(l+r+)>>;
for (i=,j,k=;i<=n;i=k++){
memset(w,,sizeof(w));mmh=;
while (h[k]>=mid&&k<=n) k++;
for (j=i;j<k;j++) if (!w[nu[sa[j]]]&&nu[sa[j]]) mmh++,w[nu[sa[j]]]=;
if (mmh*>nnm) break;
}
if (i<=n) l=mid;else r=mid-;
}
pos=;
for (i=,j,k=;i<=n;i=k++){
memset(w,,sizeof(w));mmh=;
while (h[k]>=l&&k<=n) k++;
for (j=i;j<k;j++) if (!w[nu[sa[j]]]&&nu[sa[j]]) mmh++,w[nu[sa[j]]]=;
if (mmh*>nnm) st[++pos]=sa[i];
}
if (l==) printf("?\n");else
for (int i=;i<=pos;putchar('\n'),i++)
for (int j=;j<l;j++) putchar(a[st[i]+j]+'a');
putchar('\n');
scanf("%d",&n);
}
}

3952K 750MS G++ 2114B


poj 3294的更多相关文章

  1. POJ 3294 n个串中至少一半的串共享的最长公共子串

    Life Forms Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 12484   Accepted: 3502 Descr ...

  2. Poj 3294 Life Forms (后缀数组 + 二分 + Hash)

    题目链接: Poj 3294 Life Forms 题目描述: 有n个文本串,问在一半以上的文本串出现过的最长连续子串? 解题思路: 可以把文本串用没有出现过的不同字符连起来,然后求新文本串的heig ...

  3. POJ - 3294~Relevant Phrases of Annihilation SPOJ - PHRASES~Substrings POJ - 1226~POJ - 3450 ~ POJ - 3080 (后缀数组求解多个串的公共字串问题)

    多个字符串的相关问题 这类问题的一个常用做法是,先将所有的字符串连接起来, 然后求后缀数组 和 height 数组,再利用 height 数组进行求解. 这中间可能需要二分答案. POJ - 3294 ...

  4. POJ 3294 后缀数组

    题目链接:http://poj.org/problem?id=3294 题意:给定n个字符串,求一个最长子串要求在超过一半的字符串中出现过. 如果多解按字典序输出 思路:根据<<后缀数组— ...

  5. POJ 3294 Life Forms(后缀数组+二分答案)

    [题目链接] http://poj.org/problem?id=3294 [题目大意] 求出在至少在一半字符串中出现的最长子串. 如果有多个符合的答案,请按照字典序输出. [题解] 将所有的字符串通 ...

  6. poj 3294 Life Forms - 后缀数组 - 二分答案

    题目传送门 传送门I 传送门II 题目大意 给定$n$个串,询问所有出现在严格大于$\frac{n}{2}$个串的最长串.不存在输出'?' 用奇怪的字符把它们连接起来.然后求sa,hei,二分答案,按 ...

  7. POJ 3294 Life Forms [最长公共子串加强版 后缀数组 && 二分]

    题目:http://poj.org/problem?id=3294 Life Forms Time Limit: 5000MS   Memory Limit: 65536K Total Submiss ...

  8. POJ 3294 出现在至少K个字符串中的子串

    在掌握POJ 2774(两个串求最长公共子串)以及对Height数组分组后,本题还是容易想出思路的. 首先用字符集外的不同字符连接所有串,这是为了防止两个后缀在比较时超过某个字符串的分界.二分子串的长 ...

  9. POJ 3294 Life Forms 后缀数组+二分 求至少k个字符串中包含的最长子串

    Life Forms   Description You may have wondered why most extraterrestrial life forms resemble humans, ...

  10. POJ 3294 二分找超过一半字符串中存在的子串

    题目大意: 给定n个字符串,求出现在不小于k/2个字符串中的最长子串. 二分找对应子串长度的答案,将所有字符串链接成一个长字符串求后缀数组,记录每一个位置本属于第几个字符串,利用height查询的时候 ...

随机推荐

  1. Principle-初步认识(简介)

    Principle官网 探究了一下 . 呃--作出了下边这玩意 做的好的是这样的,瞬间把自己给菜了,给大家看看,设计需要UI功夫啊 把这个用上你的界面就搞基了,图形在水平.垂直上的动态效果(*.*) ...

  2. Spring(概念)

    在本文中只讲述一些概念性的东西,因为我在开始学习JAVA的时候对这些概念性的东西总是不太理解,总结总结再感悟一下,也方便后人. 理解的不深,用通俗的语言讲一下: 百度百科这样介绍: spring框架主 ...

  3. Node: 如何控制子进程的输出

    大家知道,在一个node程序中,如果当前进程想要生成一个子进程,它可以调用child_process模块的spawn方法.spawn方法签名如下: child_process.spawn(comman ...

  4. 使用requests爬取猫眼电影TOP100榜单

    Requests是一个很方便的python网络编程库,用官方的话是"非转基因,可以安全食用".里面封装了很多的方法,避免了urllib/urllib2的繁琐. 这一节使用reque ...

  5. 关于VS2017安装的一点扩充说明(15.5)

    其实逆天不推荐自己慢慢离线,找个离线包更新下再打包更快 Key:http://www.cnblogs.com/dunitian/p/4667038.html VS完整卸载工具:https://gith ...

  6. oracle自动备份_expdp_Linux

    [oracle@hbsjxtdb1 ~]$ crontab -e 0 4 * * * /backup/script/backupexpdp.sh [oracle@hbsjxtdb1 ~]$ cront ...

  7. K:枚举的线程安全性及其序列化问题

      枚举是如何保证线程安全的且其在序列化和反序列化的操作中是单例的?   要想看源码,首先得有一个类吧,那么枚举类型到底是什么类呢?是enum吗?答案很明显不是,enum就和class一样,只是一个关 ...

  8. redis 安装方式

    1 参考网址 https://www.cnblogs.com/ahjx1628/p/6496529.html https://www.cnblogs.com/smail-bao/p/6164132.h ...

  9. linux 下安装 sphinx 服务器

    准备工作:安装需要的扩展文件 yum install make gcc g++ gcc-c++ libtool autoconf automake imake libxml2-devel expat- ...

  10. windows c++ 程序移植到Linux的一些要点

    这段时间得到一份源码,是Windows下的,调试了一把,可以正常运行,可是没有Linux版本,而实际的应用场景是要在Linux服务器上面运行 所以涉及到Windows下c++程序的移植,有同事竭力推荐 ...