后缀数组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. Network in Network

     论文要点: 用更有效的非线性函数逼近器(MLP,multilayer perceptron)代替 GLM 以增强局部模型的抽象能力.抽象能力指的模型中特征是对于同一概念的变体的不变形. 使用 gl ...

  2. ajax 操作

    ajax 操作 ajax呢,就是要做到在神不知鬼不觉的情况之下给服务端发送请求. ajax能干啥哩? 这,,,,: 利用AJAX可以做:1.注册时,输入用户名自动检测用户是否已经存在.2.登陆时,提示 ...

  3. 实现GridControl的行单元格非顺序跳转

    用GridControl控件添加数据的时候发现,有一些字段过多但是并不是每个字段都需要用户输入,每个单元格都回车跳转的时候不仅浪费时间,而且用户体验也不好,就需要单元格跳转的时候,不需要的字段可以隔过 ...

  4. ibatis的优缺点及可行性分析

    1.优点 简单: 易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现. 实用: 提供了数据映射功能,提供了对底层数据访问的封装(例如ado.net),提供了DAO框架,可以使我 ...

  5. Dapper中条件为In的写法

    今天用Dapper更新是用到了IN写法,园子里找了篇文章这样写到 传统sql in (1,2,3) 用dapper就这样写 conn.Query<Users>("SELECT * ...

  6. LinkedHashMap就这么简单【源码剖析】

    前言 声明,本文用得是jdk1.8 前面已经讲了Collection的总览和剖析List集合以及散列表.Map集合.红黑树还有HashMap基础了: Collection总览 List集合就这么简单[ ...

  7. HRBUST1522【单调队列+DP】

    题目:输入一个长度为n的整数序列(A1,A2,--,An),从中找出一段连续的长度不超过m的子序列,使得这个子序列的和最大. #include<stdio.h> #include<s ...

  8. HTML初识

    HTML初识 web服务本质 import socket def main(): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) so ...

  9. Java:import com.sun.awt.AWTUtilities;报错

    参考网址:http://stackoverflow.com/questions/860187/access-restriction-on-class-due-to-restriction-on-req ...

  10. 从感知机到 SVM,再到深度学习(二)

        这篇博文承接上一篇,详细推导了 SVM 算法,包括对偶算法,SMO 优化算法,核函数技巧等等,最后还提到用高度非线性的曲线代替超平面,就是神经网络的方法.     在第一篇中已经得到了最优间隔 ...