传送门

求 n 个串的字典序最小的最长公共子串。

和 2 个串的处理方法差不多。

把 n 个串拼接在一起,中间连上一个没有出现过的字符防止匹配过界。

求出 height 数组后二分公共子串长度给后缀数组分组。

然后 check,每一组中是否所有的字符串都包含。

直接遍历 sa 数组,第一个满足的结果就是字典序最小的。

——代码

 #include <cstdio>
#include <cstring>
#include <iostream>
#define N 900005
#define M 4001 int n, len, m, start;
int buc[N], x[N], y[N], sa[N], rank[N], height[N], belong[N];
char s[N], a[M];
bool f[M]; inline void build_sa()
{
int i, k, p;
for(i = ; i < m; i++) buc[i] = ;
for(i = ; i < len; i++) buc[x[i] = s[i]]++;
for(i = ; i < m; i++) buc[i] += buc[i - ];
for(i = len - ; i >= ; i--) sa[--buc[x[i]]] = i;
for(k = ; k <= len; k <<= )
{
p = ;
for(i = len - ; i >= len - k; i--) y[p++] = i;
for(i = ; i < len; i++) if(sa[i] >= k) y[p++] = sa[i] - k;
for(i = ; i < m; i++) buc[i] = ;
for(i = ; i < len; i++) buc[x[y[i]]]++;
for(i = ; i < m; i++) buc[i] += buc[i - ];
for(i = len - ; i >= ; i--) sa[--buc[x[y[i]]]] = y[i];
std::swap(x, y);
p = , x[sa[]] = ;
for(i = ; i < len; i++)
x[sa[i]] = y[sa[i - ]] == y[sa[i]] && y[sa[i - ] + k] == y[sa[i] + k] ? p - : p++;
if(p >= len) break;
m = p;
}
} inline void build_height()
{
int i, j, k = ;
for(i = ; i < len; i++) rank[sa[i]] = i;
for(i = ; i < len; i++)
{
if(!rank[i]) continue;
if(k) k--;
j = sa[rank[i] - ];
while(s[i + k] == s[j + k] && i + k < len && j + k < len) k++;
height[rank[i]] = k;
}
} inline bool check(int k)
{
int i, cnt = ;
memset(f, , sizeof(f));
f[belong[sa[]]] = ;
for(i = ; i < len; i++)
if(height[i] >= k)
{
if(!f[belong[sa[i]]]) cnt++;
f[belong[sa[i]]] = ;
if(cnt == n)
{
start = sa[i];
return ;
}
}
else
{
memset(f, , sizeof(f));
f[belong[sa[i]]] = ;
cnt = ;
}
return ;
} int main()
{
int i, j, l, r, mid, leng;
while(scanf("%d", &n) && n)
{
len = ;
m = ;
memset(belong, , sizeof(belong));
for(i = ; i <= n; i++)
{
scanf("%s", a);
for(j = ; a[j] ^ '\0'; j++) s[len++] = a[j];
s[len++] = '#';
belong[len] = ;
}
len--;
build_sa();
build_height();
for(i = ; i < len; i++) belong[i] += belong[i - ];
l = , r = len, leng = , start = -;
while(l <= r)
{
mid = (l + r) >> ;
if(check(mid)) leng = mid, l = mid + ;
else r = mid - ;
}
if(leng && start ^ -)
{
for(i = start; i < start + leng; i++) putchar(s[i]);
putchar('\n');
}
else puts("IDENTITY LOST");
}
return ;
}

[HDU2328]Corporate Identity(后缀数组)的更多相关文章

  1. POJ3450 Corporate Identity —— 后缀数组 最长公共子序列

    题目链接:https://vjudge.net/problem/POJ-3450 Corporate Identity Time Limit: 3000MS   Memory Limit: 65536 ...

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

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

  3. [poj3450]Corporate Identity(后缀数组)

    题意:多个字符串的最长公共子串. 解题关键:字符串的任何一个子串都是这个字符串的某个后缀的前缀.求A和B的最长公共子串等价于求A的后缀和B的后缀的最长公共前缀的最大值. 后缀数组的经典例题,连接在一起 ...

  4. hdu2328 Corporate Identity【string库使用】【暴力】【KMP】

    Corporate Identity Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  5. kuangbin专题十六 KMP&&扩展KMP HDU2328 Corporate Identity

    Beside other services, ACM helps companies to clearly state their “corporate identity”, which includ ...

  6. hdu2328 Corporate Identity 扩展KMP

    Beside other services, ACM helps companies to clearly state their “corporate identity”, which includ ...

  7. hdu2328 Corporate Identity

    地址:http://acm.hdu.edu.cn/showproblem.php?pid=2328 题目: Corporate Identity Time Limit: 9000/3000 MS (J ...

  8. POJ-3450 Corporate Identity (KMP+后缀数组)

    Description Beside other services, ACM helps companies to clearly state their “corporate identity”, ...

  9. POJ3450 Corporate Identity 【后缀数组】

    Corporate Identity Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 7662   Accepted: 264 ...

随机推荐

  1. 使用JDBC处理MySQL大文本和大数据

    LOB,Large Objects,是一种用于存储大对象的数据类型,一般LOB又分为BLOB与CLOB.BLOB通常用于存储二进制数据,比如图片.音频.视频等.CLOB通常用于存储大文本,比如小说. ...

  2. 转载:C语言的字节对齐及#pragma pack的使用

    C语言的字节对齐及#pragma pack的使用   C编译器的缺省字节对齐方式(自然对界) 在缺省情况下,C编译器为每一个变量或是数据单元按其自然对界条件分配空间. 在结构中,编译器为结构的每个成员 ...

  3. linux下 yum相关

    1.1 什么是yum源 Yellowdog Updater, Modified 一个基于RPM包管理的字符前端软件包管理器. 能够从指定的服务器自动下载RPM包并且安装,可以处理依赖性关系,并且一次安 ...

  4. bzoj题目分类

    转载于http://blog.csdn.net/creationaugust/article/details/513876231000:A+B 1001:平面图最小割,转对偶图最短路 1002:矩阵树 ...

  5. 【NOIP2016】DAY1 T2 天天爱跑步

    [NOIP2016]DAY1 T2 天天爱跑步 Description 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.?天天爱跑步?是一个养成类游戏,需要玩家每天按时 ...

  6. 1CSS简介

    -------------------------------------------------------------------------------------------------- - ...

  7. 使用UDEV SCSI规则在Oracle Linux上配置ASM

    对于使用ASM管理的磁盘来说,需要一种能够用于一致性标识磁盘设备及其正确的所属关系和权限的手段.在Linux系统中,可以使用ASMLib来执行这项任务,但是这样做的缺点是在操作系统上增加了额外的一层, ...

  8. JVM 内存分配和垃圾回收(GC)机制

    一  判断对象是否存活 垃圾收集器在对堆进行回收前,第一件事情就是要确定这些对象之中哪些还“活着”,哪些已经"死去”,即不能再被任何途径使用的对象. 1.1 引用计数法 (Reference ...

  9. Java—break跳出语句

    在开发代码时,常常会产生这样的疑惑:break跳出语句是如何应用的呢? 使用break的场景有两种:一.switch语句中.二.循环语句. 这里就不介绍switch语句,主要说一下break在循环中的 ...

  10. 查看/进入mac根目录的方式

    1.通过“前往文件夹”快捷键组合 (1)打开finder,点击上部菜单栏“前往”,然后“个人”,直接跳转. (2)快捷键组合:command + shift + G:注意:打开finder后,再快捷键 ...