POJ3450 Corporate Identity 【后缀数组】
| Time Limit: 3000MS | Memory Limit: 65536K | |
| Total Submissions: 7662 | Accepted: 2644 |
Description
Beside other services, ACM helps companies to clearly state their “corporate identity”, which includes company logo but also other signs, like trademarks. One of such companies is Internet Building Masters (IBM), which has recently asked ACM for a help with
their new identity. IBM do not want to change their existing logos and trademarks completely, because their customers are used to the old ones. Therefore, ACM will only change existing trademarks instead of creating new ones.
After several other proposals, it was decided to take all existing trademarks and find the longest common sequence of letters that is contained in all of them. This sequence will be graphically emphasized to form a new logo. Then, the old trademarks may
still be used while showing the new identity.
Your task is to find such a sequence.
Input
The input contains several tasks. Each task begins with a line containing a positive integer N, the number of trademarks (2 ≤ N ≤ 4000). The number is followed by N lines, each containing one trademark. Trademarks will be composed only from lowercase letters,
the length of each trademark will be at least 1 and at most 200 characters.
After the last trademark, the next task begins. The last task is followed by a line containing zero.
Output
For each task, output a single line containing the longest string contained as a substring in all trademarks. If there are several strings of the same length, print the one that is lexicographically smallest. If there is no such non-empty string, output
the words “IDENTITY LOST” instead.
Sample Input
3
aabbaabb
abbababb
bbbbbabb
2
xyz
abc
0
Sample Output
abb
IDENTITY LOST
1A后缀数组真是快意【模板越敲越来劲】
这道题就是求多字符串的公共最长子串
之前已经写过一个类似的了
把所有字符串分别用一个其它的标识符作为分隔连接起来【分隔符互不相同以保证不参与匹配】
注意这里的字符串比较多,分隔符就有很多,所以不能用char存,要用int存
之后就是二分长度,看看height的每个分组中是否N个串都在里面
找到最大长度再跑一次找到第一个满足要求的分组输出
#include<iostream>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define REP0(i,n) for (int i = 0; i <= (n); i++)
#define PER(i,n) for (int i = (n); i >= 1; i--)
#define Redge(u) for (int k = head[u]; k != -1; k = edge[k].next)
using namespace std;
const int maxn = 1000005,maxm = 4005,INF = 1000000000;
int N,Min,r[maxn];
char A[maxn];
int sa[maxn],rank[maxn],height[maxn],t1[maxn],t2[maxn],c[maxn],id[maxn],vis[maxm],n,m;
void SA(){
int *x = t1,*y = t2;
REP0(i,m) c[i] = 0;
REP(i,n) c[x[i] = r[i]]++;
REP(i,m) c[i] += c[i - 1];
PER(i,n) sa[c[x[i]]--] = i;
for (int k = 1; k <= n; k <<= 1){
int p = 0;
for (int i = n - k + 1; i <= n; i++) y[++p] = i;
REP(i,n) if (sa[i] - k > 0) y[++p] = sa[i] - k;
REP0(i,m) c[i] = 0;
REP(i,n) c[x[y[i]]]++;
REP(i,m) c[i] += c[i - 1];
PER(i,n) sa[c[x[y[i]]]--] = y[i];
swap(x,y);
x[sa[1]] = p = 1;
for (int i = 2; i <= n; i++)
x[sa[i]] = y[sa[i]] == y[sa[i - 1]] && y[sa[i] + k] == y[sa[i - 1] + k] ? p : ++p;
if (p >= n) break;
m = p;
}
REP(i,n) rank[sa[i]] = i;
for (int i = 1,k = 0,j; i <= n; i++){
if (k) k--;
j = sa[rank[i] - 1];
while (r[i + k] == r[j + k]) k++;
height[rank[i]] = k;
}
}
bool check(int K){
memset(vis,-1,sizeof(vis));
int cnt = 0,flag = 1;
REP(i,n){
if (id[sa[i]] == -1) {cnt = 0; ++flag; continue;}
if (height[i] < K){
cnt = 1; ++flag;
vis[id[sa[i]]] = flag;
}
else {
if (vis[id[sa[i]]] != flag) cnt++;
vis[id[sa[i]]] = flag;
}
if (cnt == N) return true;
}
return false;
}
void print(int K){
//cout<<"K:"<<K<<endl;
memset(vis,-1,sizeof(vis));
int cnt = 0,flag = 1,pos = 0;
REP(i,n){
if (id[sa[i]] == -1) {cnt = 0; ++flag; continue;}
if (height[i] < K){
cnt = 1; ++flag; pos = sa[i];
vis[id[sa[i]]] = flag;
}
else {
if (vis[id[sa[i]]] != flag) cnt++;
vis[id[sa[i]]] = flag;
}
if (cnt == N){
for (int i = 0; i < K; i++)
putchar(r[pos + i]);
puts("");
return;
}
}
}
void solve(){
int L = 0,R = Min,mid;
while (L < R){
mid = L + R + 1 >> 1;
if (check(mid)) L = mid;
else R = mid - 1;
}
if (!L) printf("IDENTITY LOST\n");
else print(L);
}
int main(){
while (~scanf("%d",&N) && N){
m = 130; n = 0; Min = INF;
REP(i,N){
scanf("%s",A + 1);
int len = strlen(A + 1); Min = min(Min,len);
for (int j = 1; j <= len; j++) r[n + j] = A[j],id[n + j] = i;
n += len; r[++n] = ++m; id[n] = -1;
}
//REP(i,n) printf("%c",isalpha(r[i]) ? r[i] : '#');cout<<endl;
SA();
//REP(i,n) cout<<sa[i]<<' ';cout<<endl;
solve();
}
return 0;
}
POJ3450 Corporate Identity 【后缀数组】的更多相关文章
- POJ3450 Corporate Identity —— 后缀数组 最长公共子序列
题目链接:https://vjudge.net/problem/POJ-3450 Corporate Identity Time Limit: 3000MS Memory Limit: 65536 ...
- [poj3450]Corporate Identity(后缀数组)
题意:多个字符串的最长公共子串. 解题关键:字符串的任何一个子串都是这个字符串的某个后缀的前缀.求A和B的最长公共子串等价于求A的后缀和B的后缀的最长公共前缀的最大值. 后缀数组的经典例题,连接在一起 ...
- poj 3518 Corporate Identity 后缀数组->多字符串最长相同连续子串
题目链接 题意:输入N(2 <= N <= 4000)个长度不超过200的字符串,输出字典序最小的最长公共连续子串; 思路:将所有的字符串中间加上分隔符,注:分隔符只需要和输入的字符不同, ...
- POJ-3450 Corporate Identity (KMP+后缀数组)
Description Beside other services, ACM helps companies to clearly state their “corporate identity”, ...
- POJ3450 Corporate Identity
后缀数组. 解决多个字符串的最长公共子串. 采用对长度的二分,将子串按height分组,每次判断是否在每个字符串中都出现过. 复杂度O(NlogN) By:大奕哥 #include<cstrin ...
- [HDU2328]Corporate Identity(后缀数组)
传送门 求 n 个串的字典序最小的最长公共子串. 和 2 个串的处理方法差不多. 把 n 个串拼接在一起,中间连上一个没有出现过的字符防止匹配过界. 求出 height 数组后二分公共子串长度给后缀数 ...
- POJ3080 POJ3450Corporate Identity(广义后缀自动机||后缀数组||KMP)
Beside other services, ACM helps companies to clearly state their “corporate identity”, which includ ...
- hdu2328 Corporate Identity【string库使用】【暴力】【KMP】
Corporate Identity Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- kuangbin带你飞 后缀数组 题解
2份模板 DC3 . 空间复杂度O3N 时间复杂度On #define F(x) ((x) / 3 + ((x) % 3 == 1 ? 0 : tb)) #define G(x) ((x) < ...
随机推荐
- Python序列删除重复数据
## 对于列表来说,若不保持原有顺序,可以直接转换为set删除重复数据 nums = [1,2,32,2,2,4,3,2,3,42] nums = list(set(nums)) print(nums ...
- Java源码解析——集合框架(五)——HashMap源码分析
HashMap源码分析 HashMap的底层实现是面试中问到最多的,其原理也更加复杂,涉及的知识也越多,在项目中的使用也最多.因此清晰分析出其底层源码对于深刻理解其实现有重要的意义,jdk1.8之后其 ...
- mac phpstorm 破解方法
方法参考如下链接: 来源:http://www.cnblogs.com/zyliang/p/6148960.html
- 3D Food Printing【3D食物打印】
3D Food Printing There's new frontier in 3D printing that's begining to come into focus: food. 3D打印的 ...
- 安装 Node.js v8.0 生产环境
步骤://center os 上把apt-get换成yum 第一步:进入服务器升级工具包 sudo apt-get update 第二步:安装git sudo apt-get install git ...
- Python3爬虫(七) 解析库的使用之pyquery
Infi-chu: http://www.cnblogs.com/Infi-chu/ pyquery专门针对CSS和jQuery的操作处理 1.初始化字符串初始化 from pyquery impor ...
- 剑指offer题目系列二
本篇延续上一篇,介绍<剑指offer>第二版中的四个题目:从尾到头打印链表.用两个栈实现队列.旋转数组的最小数字.二进制中1的个数. 5.从尾到头打印链表 题目:输入一个链表的头结点,从尾 ...
- CentOS搭建Sqoop环境
Sqoop是一个用来将Hadoop(Hive.HBase)和关系型数据库中的数据相互转移的工具,可以将一个关系型数据库(例如:MySQL ,Oracle ,Postgres等)中的 ...
- windows系统下npm升级的正确姿势以及原理
本文来自网易云社区 作者:陈观喜 网上关于npm升级很多方法多种多样,但是在windows系统下不是每种方法都会正确升级.其中在windows系统下主要的升级方法有以下三种: 首先最暴力的方法删掉no ...
- MySQL高可用之PXC安装部署
Preface Today,I'm gonna implement a PXC,Let's see the procedure. Framework Hostname IP P ...