记录编号 |
9734 |
评测结果 |
AAAAAAAAAAAAAAAAAAAA |
题目名称 |
[POI 2000] 最长公共子串 |
最终得分 |
100 |
用户昵称 |
BYVoid |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
0.046 s |
提交时间 |
2009-04-16 20:55:58 |
内存使用 |
0.78 MiB |
显示代码纯文本
/*
* Problem: POI2000 pow
* Author: Guo Jiabao
* Time: 2009.4.16 19:22
* State: Unsolved
* Memo: 多串最长公共子串 后缀数组 二分答案
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
const int MAXL=10011,MAXN=6;
using namespace std;
struct SuffixArray
{
struct RadixElement
{
int id,k[2];
}RE[MAXL],RT[MAXL];
int N,A[MAXL],SA[MAXL],Rank[MAXL],Height[MAXL],C[MAXL];
void RadixSort()
{
int i,y;
for (y=1;y>=0;y--)
{
memset(C,0,sizeof(C));
for (i=1;i<=N;i++) C[RE[i].k[y]]++;
for (i=1;i<MAXL;i++) C[i]+=C[i-1];
for (i=N;i>=1;i--) RT[C[RE[i].k[y]]--]=RE[i];
for (i=1;i<=N;i++) RE[i]=RT[i];
}
for (i=1;i<=N;i++)
{
Rank[ RE[i].id ]=Rank[ RE[i-1].id ];
if (RE[i].k[0]!=RE[i-1].k[0] || RE[i].k[1]!=RE[i-1].k[1])
Rank[ RE[i].id ]++;
}
}
void CalcSA()
{
int i,k;
RE[0].k[0]=-1;
for (i=1;i<=N;i++)
RE[i].id=i,RE[i].k[0]=A[i],RE[i].k[1]=0;
RadixSort();
for (k=1;k+1<=N;k*=2)
{
for (i=1;i<=N;i++)
RE[i].id=i,RE[i].k[0]=Rank[i],RE[i].k[1]=i+k<=N?Rank[i+k]:0;
RadixSort();
}
for (i=1;i<=N;i++)
SA[ Rank[i] ]=i;
}
void CalcHeight()
{
int i,k,h=0;
for (i=1;i<=N;i++)
{
if (Rank[i]==1)
h=0;
else
{
k=SA[Rank[i]-1];
if (--h<0) h=0;
for (;A[i+h]==A[k+h];h++);
}
Height[Rank[i]]=h;
}
}
}SA;
int N,Ans,Bel[MAXL];
char S[MAXL];
void init()
{
int i;
freopen("pow.in","r",stdin);
freopen("pow.out","w",stdout);
scanf("%d",&N);
SA.N=0;
for (i=1;i<=N;i++)
{
scanf("%s",S);
for (char *p=S;*p;p++)
{
SA.A[++SA.N]=*p-'a'+1;
Bel[SA.N]=i;
}
if (i<N)
SA.A[++SA.N]=30+i;
}
}
bool check(int A)
{
int i,j,k;
bool ba[MAXN];
for (i=1;i<=SA.N;i++)
{
if (SA.Height[i]>=A)
{
for (j=i;SA.Height[j]>=A && j<=SA.N;j++);
j--;
memset(ba,0,sizeof(ba));
for (k=i-1;k<=j;k++)
ba[Bel[SA.SA[k]]]=true;
for (k=1;ba[k] && k<=N;k++);
if (k==N+1)
return true;
i=j;
}
}
return false;
}
void solve()
{
int a,b,m;
SA.CalcSA();
SA.CalcHeight();
a=0;b=SA.N;
while (a+1<b)
{
m=(a+b)/2;
if (check(m))
a=m;
else
b=m-1;
}
if (check(b))
a=b;
Ans=a;
}
int main()
{
init();
solve();
printf("%d\n",Ans);
return 0;
}