传送门

求 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. git ldap

    https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/README.md ldap : enabled : true host : 'ope ...

  2. MSP430 G2553 Timer 中断总结

    目前总共用到了四个中断向量,我觉得已经把G2553的所有定时器中断都用到了. 定时器有两个,TA0与TA1,每个定时器又有两个中断向量 1,CCR0到达时的中断,在计数模式时候很有用,平时定时器的基本 ...

  3. IOException 简单解决方法

    java.lang.IllegalStateException异常解决方法 这个异常大多数是由文件读取,下载时抛出,但是偶尔也会由类型转换时异常抛出此异常. 错误:Optional int param ...

  4. Gym - 101972B Arabella Collegiate Programming Contest (2018) B. Updating the Tree 树DFS

    题面 题意:T组数据,每次给你1e5个点的树(1为根),每个点有一权值,询问1-n每个节点的子树中, 至少修改几个点的权值(每次都可以任意修改),才能让子树中任意2点的距离==他们权值差的绝对值 无解 ...

  5. Akka源码分析-Actor创建(续)

    在上一遍博客中,我们已经分析了actor创建的大致过程,但只是涉及到了Dipatcher/Mailbox/ActorCell/InternalActorRef等对象的创建,并没有介绍我们自定义的继承A ...

  6. 机器学习——Day 3 多元线性回归

    写在开头 由于某些原因开始了机器学习,为了更好的理解和深入的思考(记录)所以开始写博客. 学习教程来源于github的Avik-Jain的100-Days-Of-MLCode 英文版:https:// ...

  7. JavaScript--编程练习1

    使用JS完成一个简单的计算器功能.实现2个输入框中输入整数后,点击第三个输入框能给出2个整数的加减乘除. 提示:获取元素的值设置和获取方法为:例:赋值:document.getElementById( ...

  8. SCOI2014总结

    似乎还没有写过SCOI的总结,今天补上,权当填坑. PS:CDQZ的看到了不要到处黑 SCOI-2014应该算是我的小高考,感觉拿住一本招的瓶颈就在这里.加之NOIp只有400分有点拖后腿,所以很早就 ...

  9. 无法定位程序输入点_except_handler4_common于动态链接库msvcrt.dll

    这是由于sp3加载的驱动造成的:只需要将C:\WINDOWS\system32\dwmapi.dll重新命名一下即可以解决. 可以调试程序当系统加载到“c:\Program Files\China M ...

  10. pd_ds 之 hash

    http://attack.cf/?post=23 打个广告....