后缀数组height+二分

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<iostream>
#define MAXN 100*10000+10
#define pii pair<int,int>
using namespace std;
struct Node{
pii v;
int p;
friend bool operator < (const Node &p1,const Node &p2){
return (p1.v<p2.v);
}
}tsa[MAXN]; char s[MAXN];
int T,n;
int b[],p[MAXN],ans[MAXN];
int rk[MAXN],sa[MAXN];
void build_sa(){
for(int i=;i<=n;i++){
rk[i]=s[i]-;
}
for(int k=;k<=n;k<<=){
for(int i=;i<=n-k;i++){
tsa[i].v=make_pair(rk[i],rk[i+k]);
tsa[i].p=i;
}
for(int i=n-k+;i<=n;i++){
tsa[i].v=make_pair(rk[i],);
tsa[i].p=i;
}
sort(tsa+,tsa+n+);
int cnt=;
for(int i=;i<=n;i++){
if(!cnt||tsa[i].v!=tsa[i-].v){
cnt++;
}
rk[tsa[i].p]=cnt;
}
if(cnt>=n)break;
}
for(int i=;i<=n;i++){
sa[rk[i]]=i;
}
}
int height[MAXN];
void build_height(){
int k=;
for(int i=;i<=n;i++){
if(k)k--;
int j=sa[rk[i]-];
while(s[i+k]==s[j+k]){
k++;
}
height[rk[i]]=k;
}
}
void init(){
n=;
char tmp='z'+;
for(int i=;i<=T;i++){
scanf("%s",s+n+);
int t=n;
n=strlen(s+);
s[++n]=(tmp++);
for(int j=t+;j<=n;j++){
p[j]=i;
}
}
build_sa();
build_height();
}
int check(int x){
memset(b,,sizeof(b));
int cnt=;
int ret=;
for(int i=;i<=n;i++){
if(height[i]>=x){
if(!cnt){
if(p[sa[i]]==p[sa[i-]]){
cnt=;
}
else{
cnt=;
}
b[p[sa[i]]]=b[p[sa[i-]]]=;
}
else if(!b[p[sa[i]]]){
b[p[sa[i]]]=;
cnt++;
}
if(cnt>T/){
ans[sa[i]]=;
ret=;
}
}
else{
memset(b,,sizeof(b));
cnt=;
}
}
return ret;
}
vector<string> vs;
string ept;
void print(int x){
vs.clear();
string ts(s,n+);
for(int i=;i<=n;i++){
if(ans[i]){
string t;
t=ept;
for(int j=i;j<=i+x-;j++){
t+=s[j];
}
vs.push_back(t);
}
}
sort(vs.begin(),vs.end());
vs.erase(unique(vs.begin(),vs.end()),vs.end());
for(int i=;i<vs.size();i++){
cout<<vs[i]<<endl;
}
}
void solve(){
// for(int i=1;i<=n;i++){
// for(int j=sa[i];j<=n;j++){
// printf("%c",s[j]);
// }
// printf("\n");
// }
// for(int i=6;i<=n;i++){
// printf("%d\n",check(i));
// }
int L=,R=n;
while(R-L>){
int mid=(L+R)/;
if(check(mid)){
L=mid;
}
else{
R=mid;
}
}
memset(ans,,sizeof(ans));
if(R&&check(R)){
print(R);
}
else{
if(L&&check(L)){
print(L);
}
else{
printf("?\n");
}
}
}
int main()
{
// freopen("data.in","r",stdin);
// freopen("my.out","w",stdout);
int flag=;
while(){
scanf("%d",&T);
if(!T)break;
if(flag){
printf("\n");
}
else{
flag=;
}
if(T==){
scanf("%s",s+);
printf("%s\n",s+);
continue;
}
init();
solve();
}
return ;
}

UVA - 11107:Life Forms的更多相关文章

  1. 后缀数组练习4:Life Forms

    有一个细节不是特别懂,然后的话细节有点多,就是挺难发现的那一种,感谢大佬的博客 1470: 后缀数组4:Life Forms poj3294 时间限制: 1 Sec  内存限制: 128 MB提交: ...

  2. 后缀数组 UVA 11107 Life Forms

    题目链接 题意:训练指南P223 分析:二分长度,把所有字符串连成一个字符串,中间用不同的字符分隔(这是为了保证匹配长度始终在一个字符串内).height数组分段,vis数组标记哪些字符串被访问了,如 ...

  3. UVa 11107 (后缀数组 二分) Life Forms

    利用height值对后缀进行分组的方法很常用,好吧,那就先记下了. 题意: 给出n个字符串,求一个长度最大的字符串使得它在超过一半的字符串中出现. 多解的话,按字典序输出全部解. 分析: 在所有输入的 ...

  4. uva 11107 Life Forms

    题意:给你N个串,求一个串在大于等于N/2的模板串中连续出现.如果有多解按字典序最小输出. 白书模板题.二分答案+合并模板串成一个新串,扫秒新串的height数组. 考查后缀数组+LCP #inclu ...

  5. 后缀数组LCP + 二分 - UVa 11107 Life Forms

    Life Forms Problem's Link Mean: 给你n个串,让你找出出现次数大于n/2的最长公共子串.如果有多个,按字典序排列输出. analyse: 经典题. 直接二分判断答案. 判 ...

  6. UVA - 11107 Life Forms (广义后缀自动机)

    题意:给你n个字符串,求出在超过一半的字符串中出现的所有子串中最长的子串,按字典序输出. 对这n个字符串建广义后缀自动机,建完后每个字符串在自动机上跑一遍,沿fail树向上更新所有子串结点的出现次数( ...

  7. UVA - 11107 Life Forms (广义后缀自动机+后缀树/后缀数组+尺取)

    题意:给你n个字符串,求出在超过一半的字符串中出现的所有子串中最长的子串,按字典序输出. 这道题算是我的一个黑历史了吧,以前我的做法是对这n个字符串建广义后缀自动机,然后在自动机上dfs,交上去AC了 ...

  8. UVA 11107 Life Forms——(多字符串的最长公共子序列,后缀数组+LCP)

    题意: 输入n个序列,求出一个最大长度的字符串,使得它在超过一半的DNA序列中连续出现.如果有多解,按照字典序从小到大输出所有解. 分析:这道题的关键是将多个字符串连接成一个串,方法是用不同的分隔符把 ...

  9. POJ 3294 UVA 11107 Life Forms 后缀数组

    相同的题目,输出格式有区别. 给定n个字符串,求最长的子串,使得它同时出现在一半以上的串中. 不熟悉后缀数组的童鞋建议先去看一看如何用后缀数组计算两个字符串的最长公共子串 Ural1517 这道题的思 ...

随机推荐

  1. CocoaPods 基础知识--------安装 及 使用第三方库

    极客学院:http://www.jikexueyuan.com/course/2665_2.html?ss=1

  2. android之SVG制作与应用

    文章解析及例子:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0825/3362.html 工具:Photoshop CC+sv ...

  3. D的下L

    D的小L 时间限制:4000 ms  |  内存限制:65535 KB 难度:2   描述       一天TC的匡匡找ACM的小L玩三国杀,但是这会小L忙着哩,不想和匡匡玩但又怕匡匡生气,这时小L给 ...

  4. prop attr 到底哪里不一样?

    好吧 首先承认错误  说好的每天进行一次只是总结  但是我没坚持住 准确的来说 我并没有每天会学到了东西 但是 我一直在持续努力着  以后应该不会每天都写  但是自己觉得有用的  或者想加强记忆的 可 ...

  5. wamp的mysql设置用户名和密码

    wamp下修改mysql root用户的登录密码 感谢作者:http://www.3lian.com/edu/2014/02-25/131010.html               1.安装好wam ...

  6. clang++ 链接问题 和 VS Code

    clang++ 链接问题 和 VS Code 如果你在windows上使用clang 并且同时安装有vs和mingw, clang链接是会自动使用msvs, 链接时会有LINK error LINK ...

  7. DDD实战进阶第一波(二):开发一般业务的大健康行业直销系统(搭建支持DDD的轻量级框架一)

    要实现软件设计.软件开发在一个统一的思想.统一的节奏下进行,就应该有一个轻量级的框架对开发过程与代码编写做一定的约束. 虽然DDD是一个软件开发的方法,而不是具体的技术或框架,但拥有一个轻量级的框架仍 ...

  8. 第四章 使用jQuery操作DOM

    第四章 使用jQuery操作DOM 一.DOM操作 在jQuery中的DOM操作主要可分为样式操作.文本和value属性值操作.节点操作: 节点操作又包含属性操作.节点遍历和CSS-DOM操作. 其中 ...

  9. Python内置函数(15)——memoryview

    英文文档: class memoryview(obj) memoryview objects allow Python code to access the internal data of an o ...

  10. JWT

    Web安全通讯之Token与JWT http://blog.csdn.net/wangcantian/article/details/74199762 javaweb多说本地身份说明(JWT)之小白技 ...