poj 3294 Life Forms【SA+二分】
先加入未出现字符间隔把n个串连起来,注意如果串开的char这个间隔字符不能溢出,把这个接起来的串跑SA,二分答案k,判断的时候把连续一段he>=k的分成一组,然后看着一段是否包含了>n/2的串的后缀。
统计是否出现这里可以用时间戳优化visit数组,就不用每次memset了
输出答案的时候和二分判断一样,找到合法的子串就输出
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=200005;
int m,n,wa[N],wb[N],wv[N],wsu[N],sa[N],rk[N],he[N],v[N],ti,de,bl[N];
char s[N],t[N];
bool cmp(int r[],int a,int b,int l)
{
return r[a]==r[b]&&r[a+l]==r[b+l];
}
void saa(char r[],int n,int m)
{
int *x=wa,*y=wb;
for(int i=0;i<=m;i++)
wsu[i]=0;
for(int i=1;i<=n;i++)
wsu[x[i]=r[i]]++;
for(int i=1;i<=m;i++)
wsu[i]+=wsu[i-1];
for(int i=n;i>=1;i--)
sa[wsu[x[i]]--]=i;
for(int j=1,p=1;j<n&&p<n;j<<=1,m=p)
{
p=0;
for(int i=n-j+1;i<=n;i++)
y[++p]=i;
for(int i=1;i<=n;i++)
if(sa[i]>j)
y[++p]=sa[i]-j;
for(int i=1;i<=n;i++)
wv[i]=x[y[i]];
for(int i=0;i<=m;i++)
wsu[i]=0;
for(int i=1;i<=n;i++)
wsu[wv[i]]++;
for(int i=1;i<=m;i++)
wsu[i]+=wsu[i-1];
for(int i=n;i>=1;i--)
sa[wsu[wv[i]]--]=y[i];
swap(x,y);
p=1;
x[sa[1]]=1;
for(int i=2;i<=n;i++)
x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p:++p;
}
for(int i=1;i<=n;i++)
rk[sa[i]]=i;
for(int i=1,j,k=0;i<=n;he[rk[i++]]=k)
for(k?k--:0,j=sa[rk[i]-1];r[i+k]==r[j+k];k++);
}
bool ok(int w)
{
for(int i=2,la;i<=n;i=la+1)
{
la=i;
ti++;
int sm=0;
v[bl[sa[la-1]]]=ti,sm++;
while(he[la]>=w)
{
if(v[bl[sa[la]]]!=ti)
v[bl[sa[la]]]=ti,sm++;
la++;
}//cerr<<i<<" "<<la<<" "<<sm<<endl;
if(sm>m/2)
return 1;
}
return 0;
}
int main()
{
while(scanf("%d",&m)&&m)
{
n=0,de=26;
for(int j=1;j<=m;j++)
{
scanf("%s",t+1);
for(int i=1,len=strlen(t+1);i<=len;i++)
s[++n]=t[i]-'a',bl[n]=j;
s[++n]=++de,bl[n]=j;
}
saa(s,n,200);
int l=0,r=1000,ans=0;
while(l<=r)
{
int mid=(l+r)>>1;
if(ok(mid))
l=mid+1,ans=mid;
else
r=mid-1;
}//cerr<<ans<<endl;
if(ans==0)
{
puts("?\n");
continue;
}
for(int i=2,la;i<=n;i=la+1)
{
la=i;
ti++;
int sm=0;
v[bl[sa[la-1]]]=ti,sm++;
while(he[la]>=ans)
{
if(v[bl[sa[la]]]!=ti)
v[bl[sa[la]]]=ti,sm++;
la++;
}
if(sm>m/2)
{
for(int j=0;j<ans;j++)
if(s[sa[i]+j]<=26)
printf("%c",s[sa[i]+j]+'a');
puts("");
}
}
puts("");
}
return 0;
}
poj 3294 Life Forms【SA+二分】的更多相关文章
- Poj 3294 Life Forms (后缀数组 + 二分 + Hash)
题目链接: Poj 3294 Life Forms 题目描述: 有n个文本串,问在一半以上的文本串出现过的最长连续子串? 解题思路: 可以把文本串用没有出现过的不同字符连起来,然后求新文本串的heig ...
- POJ 3294 Life Forms [最长公共子串加强版 后缀数组 && 二分]
题目:http://poj.org/problem?id=3294 Life Forms Time Limit: 5000MS Memory Limit: 65536K Total Submiss ...
- POJ 3294 Life Forms(后缀数组+二分答案)
[题目链接] http://poj.org/problem?id=3294 [题目大意] 求出在至少在一半字符串中出现的最长子串. 如果有多个符合的答案,请按照字典序输出. [题解] 将所有的字符串通 ...
- poj 3294 Life Forms - 后缀数组 - 二分答案
题目传送门 传送门I 传送门II 题目大意 给定$n$个串,询问所有出现在严格大于$\frac{n}{2}$个串的最长串.不存在输出'?' 用奇怪的字符把它们连接起来.然后求sa,hei,二分答案,按 ...
- POJ 3294 Life Forms 后缀数组+二分 求至少k个字符串中包含的最长子串
Life Forms Description You may have wondered why most extraterrestrial life forms resemble humans, ...
- 字符串(后缀数组):POJ 3294 Life Forms
Life Forms Description You may have wondered why most extraterrestrial life forms resemble humans, d ...
- poj 3294 Life Forms
后缀数组的题目,把后缀连接起来,这个还是先二分答案,然后选取一段连续的height值,判断这些height代表的后缀有没有覆盖一半以上的字符串. 得出答案的长度之后还要在枚举连续的heigh,判断有没 ...
- poj 3294 Life Forms(后缀数组)
题意:给你最多100个字符串,求最长的且是一半以上的字符串的公共子串,如果有多个,按字典序输出. 思路:先把各个串拼起来,中间加上一个之前未出现过的字符,然后求后缀.然后根据h数组和sa数组,求出最长 ...
- POJ 3294 n个串中至少一半的串共享的最长公共子串
Life Forms Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 12484 Accepted: 3502 Descr ...
随机推荐
- 安卓2.3 js解析问题 split()
安卓2.3版本号解析错误,split和parseInt都会把09和08都解析成0,07下面解析没有问题.解决的方法是直接取个位数. function getYMD(yMd){ var dArray=n ...
- css 滤镜之AlphaImageLoader
CreateTime--2017年12月25日17:05:37 Author:Marydon ie滤镜特效之AlphaImageLoader 作用: 用于设置背景图片特效样式 使用条件: IE8及 ...
- 新生入学V3.0颗粒归仓
新生入学系统V3.0接近尾声.每次做项目都有不一样的收获.V1.0,V2.0主要是熟悉了整个项目流程是怎样进行的,可行性分析--需求分析(原型图Axure)--实体设计(PD)--类图时序图(EA)- ...
- 【Unity 3D 游戏开发】Unity3D 入门 - 工作区域介绍 与 入门演示样例
一. 工作区域具体解释 1. Scence视图 (场景设计面板) scence视图简单介绍 : 展示创建的游戏对象, 能够对全部的游戏对象进行 移动, 操作 和 放置; -- 演示样例 : 创建一个球 ...
- archlinux yaourt安装 以及出错细节 database file for "archlinuxfr" does not exist.
archlinux yaourt安装 但一直报错如下: :: Synchronizing package databases... core is up to date extra is u ...
- CodeForces 24D Broken robot(期望+高斯消元)
CodeForces 24D Broken robot 大致题意:你有一个n行m列的矩形板,有一个机器人在开始在第i行第j列,它每一步会随机从可以选择的方案里任选一个(向下走一格,向左走一格,向右走一 ...
- 谈谈Paxos一致性算法和一致性这个名词
转自:http://www.cnblogs.com/esingchan/p/3917718.html 维基的简介:Paxos算法是莱斯利·兰伯特(Leslie Lamport,就是 LaTeX 中的& ...
- Mysql的Merge存储引擎实现分表查询
对于数据量很大的一张表,i/o效率底下,分表势在必行! 使用程序分,对不同的查询,分配到不同的子表中,是个解决方案,但要改代码,对查询不透明. 好在mysql 有两个解决方案: Partition(分 ...
- safair 的css hack
在css里面使用[;attribute:value;] css参考如下: .header-share li{float: right; margin-left: 20px; [;width: 50px ...
- Codeforces Round #106 (Div. 2) D. Coloring Brackets —— 区间DP
题目链接:https://vjudge.net/problem/CodeForces-149D D. Coloring Brackets time limit per test 2 seconds m ...