题目链接:http://poj.org/problem?id=3450

题目分类:后缀数组

题意:求n个串的最长公共字串(输出字串)

//#include<bits/stdc++.h>
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<string.h> using namespace std; #define N 200005 int wa[N],wb[N],wsf[N],wv[N],sa[N];
int rank[N],height[N],s[N];
//sa:字典序中排第i位的起始位置在str中第sa[i]
//rank:就是str第i个位置的后缀是在字典序排第几
//height:字典序排i和i-1的后缀的最长公共前缀
int cmp(int *r,int a,int b,int k)
{
return r[a]==r[b]&&r[a+k]==r[b+k];
}
void getsa(int *r,int *sa,int n,int m)//n要包含末尾添加的0
{
int i,j,p,*x=wa,*y=wb,*t;
for(i=; i<m; i++) wsf[i]=;
for(i=; i<n; i++) wsf[x[i]=r[i]]++;
for(i=; i<m; i++) wsf[i]+=wsf[i-];
for(i=n-; i>=; i--) sa[--wsf[x[i]]]=i;
p=;
j=;
for(; p<n; j*=,m=p)
{
for(p=,i=n-j; i<n; i++) y[p++]=i;
for(i=; i<n; i++) if(sa[i]>=j) y[p++]=sa[i]-j;
for(i=; i<n; i++) wv[i]=x[y[i]];
for(i=; i<m; i++) wsf[i]=;
for(i=; i<n; i++) wsf[wv[i]]++;
for(i=; i<m; i++) wsf[i]+=wsf[i-];
for(i=n-; i>=; i--) sa[--wsf[wv[i]]]=y[i];
t=x;
x=y;
y=t;
x[sa[]]=;
for(p=,i=; i<n; i++)
x[sa[i]]=cmp(y,sa[i-],sa[i],j)? p-:p++;
}
}
void getheight(int *r,int n)//n不保存最后的0
{
int i,j,k=;
for(i=; i<=n; i++) rank[sa[i]]=i;
for(i=; i<n; i++)
{
if(k)
k--;
else
k=;
j=sa[rank[i]-];
while(r[i+k]==r[j+k])
k++;
height[rank[i]]=k;
}
} char str[N],ans[N];
int id[N],vis[]; bool check(int mid,int n,int k)
{
int i,j,cnt = ;
memset(vis,,sizeof(vis));
for(i = ; i<=n; i++)
{
if(height[i]<mid)
{
memset(vis,,sizeof(vis));
cnt = ;
continue;
}
if(!vis[id[sa[i-]]])
{
cnt++;
vis[id[sa[i-]]] = ;
}
if(!vis[id[sa[i]]])
{
cnt++;
vis[id[sa[i]]] = ;
}
if(cnt == k)
{
for(j = ; j<mid; j++)
ans[j] = s[sa[i]+j];
ans[mid] = '\0';
return ;
}
}
return ;
} int main()
{
int n,i,j,k,len;
while(~scanf("%d",&k),k)
{
n = ;
for(i = ; i<k; i++)
{
scanf("%s",str);
len = strlen(str);
for(j = ; j<len; j++)
{
s[n] = str[j];
id[n] = i;
n++;
}
s[n] = '#'+i;
id[n] = '#'+i;
n++;
}
s[n] = ;
getsa(s,sa,n+,);
getheight(s,n);
int l = ,r = len,mid,flag = ;
while(l<=r)
{
mid = (l+r)/;
if(check(mid,n,k))
{
flag = ;
l=mid+;
}
else
r=mid-;
}
if(flag)
printf("%s\n",ans);
else
printf("IDENTITY LOST\n");
} return ;
}

poj 3450 Corporate Identity的更多相关文章

  1. POJ 3450 Corporate Identity(KMP)

    [题目链接] http://poj.org/problem?id=3450 [题目大意] 求k个字符串的最长公共子串,如果有多个答案,则输出字典序最小的. [题解] 我们对第一个串的每一个后缀和其余所 ...

  2. POJ 3450 Corporate Identity (KMP,求公共子串,方法很妙)

    http://blog.sina.com.cn/s/blog_74e20d8901010pwp.html我采用的是方法三. 注意:当长度相同时,取字典序最小的. #include <iostre ...

  3. POJ 3450 Corporate Identity kmp+最长公共子串

    枚举长度最短的字符串的所有子串,再与其他串匹配. #include<cstdio> #include<cstring> #include<algorithm> #i ...

  4. POJ 3450 Corporate Identity (KMP+暴搞)

    题意: 给定N个字符串,寻找最长的公共字串,如果长度相同,则输出字典序最小的那个. 找其中一个字符串,枚举它的所有的字串,然后,逐个kmp比较.......相当暴力,可二分优化. #include & ...

  5. POJ 3450 Corporate Identity KMP解决问题的方法

    这个问题,需要一组字符串求最长公共子,其实灵活运用KMP高速寻求最长前缀. 请注意,意大利愿父亲:按照输出词典的顺序的规定. 另外要提醒的是:它也被用来KMP为了解决这个问题,但是很多人认为KMP使用 ...

  6. POJ 题目3450 Corporate Identity(KMP 暴力)

    Corporate Identity Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 5493   Accepted: 201 ...

  7. poj 3518 Corporate Identity 后缀数组->多字符串最长相同连续子串

    题目链接 题意:输入N(2 <= N <= 4000)个长度不超过200的字符串,输出字典序最小的最长公共连续子串; 思路:将所有的字符串中间加上分隔符,注:分隔符只需要和输入的字符不同, ...

  8. 字符串截取模板 && POJ 3450、3080 ( 暴力枚举子串 && KMP匹配 )

    //截取字符串 ch 的 st~en 这一段子串返回子串的首地址 //注意用完需要根据需要最后free()掉 char* substring(char* ch,int st,int en) { ; c ...

  9. POJ - 3450

    题目链接:http://poj.org/problem?id=3450 Corporate Identity Time Limit: 3000MS   Memory Limit: 65536K Tot ...

随机推荐

  1. 面试中的Singleton

      引子 “请写一个Singleton.”面试官微笑着和我说. “这可真简单.”我心里想着,并在白板上写下了下面的Singleton实现: 1 class Singleton 2 { 3 public ...

  2. elasticsearch的javaAPI之query

    elasticsearch的javaAPI之query API the Search API同意运行一个搜索查询,返回一个与查询匹配的结果(hits). 它能够在跨一个或多个index上运行, 或者一 ...

  3. Ubuntu中查看硬盘分区UUID的方法(所有Linux目录的解释)

    在Ubuntu中UUID的两种获取方法,至于UUID是什么,你可以大概理解为分区的标识符,像条形码那样. 在终端中输入下面的命令就可心查看到分区UUID了.命令1.sudo blkid 命令2.ls ...

  4. 全面解读Python Web开发框架Django

    全面解读Python Web开发框架Django Django是一个开源的Web应用框架,由Python写成.采用MVC的软件设计模式,主要目标是使得开发复杂的.数据库驱动的网站变得简单.Django ...

  5. Hadoop: the definitive guide 第三版 拾遗 第十三章 之HBase起步

    指南上这一章的开篇即提出:HBase是一个分布式的.面向列的开源数据库.如果需要实时的随机读/写超大规模数据集,HBase无疑是一个好的选择. 简介 HBase 是一个高可靠性.高性能.面向列.可伸缩 ...

  6. shell语法简单介绍

    一.基本的语法 1.1.shell文件开头 shell文件必须以以下的行開始(必须方在文件的第一行):  #!/bin/sh  符号#!用来告诉系统它后面的參数是用来运行该文件的程序.在这个样例中我们 ...

  7. VC2008下使用OpenSSL 1.0.0g(免编译)

    OpenSSL整个软件包大概可以分成三个主要的功能部分:密码算法库.SSL协议库以及应用程序. 官网:http://www.openssl.org/OpenSSL for Windows:http:/ ...

  8. 基于visual Studio2013解决面试题之0604O(1)时间复杂度删除链表节点

     题目

  9. boost asio io_service学习笔记

    构造函数 构造函数的主要动作就是调用CreateIoCompletionPort创建了一个初始iocp. Dispatch和post的区别 Post一定是PostQueuedCompletionSta ...

  10. SRM 583 Div II Level One:SwappingDigits

    题目来源:http://community.topcoder.com/stat?c=problem_statement&pm=12609 #include <iostream> # ...