 /**//*
【题目】给定n个串,求一个最大子串长度,使得它或者它的逆向串在每个串中出现。
【分析】先把每个串倒序复制一遍,然后二分,分组。只要每个组里面有N个不同的串就满足条件
*/
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 20000+5
#define min(a,b) ((a)<(b)?(a):(b))
char s[maxn],str[maxn];
int sa[maxn],h[maxn],height[maxn],rank[maxn];
int k,n;
int minlen;
int m;
int belong[maxn];
bool cmp1(const int & a,const int & b)
  {
return (s[a]<s[b]);
}
bool cmp2(const int & a,const int & b)
  {
return (rank[a]<rank[b] || (rank[a]==rank[b]&&
(a+k<n?rank[a+k]:-1)<(b+k<n?rank[b+k]:-1)));
}
void suffixArray()
  {
int i,j;
for(i=0;i<n;i++)
sa[i]=i;
sort(sa,sa+n,cmp1);
for(i=0;i<n;i++)
 {
if(i==0||s[sa[i]]!=s[sa[i-1]])
rank[sa[i]]=i;
else rank[sa[i]]=rank[sa[i-1]];
}
for(k=1;k<n;k*=2)
 {
sort(sa,sa+n,cmp2);
for(i=0;i<n;i++)
 {
if( i==0 || (cmp2(sa[i],sa[i-1])||cmp2(sa[i-1],sa[i])) )
h[sa[i]]=i;
else h[sa[i]]=h[sa[i-1]];
}
memcpy(rank, h, n * sizeof(int));
}

height[0] = 0;
for(i = 0, j = 0; i < n; i++)
 {
if(rank[i]>0)
 {
while(s[sa[rank[i] - 1] + j] == s[i + j])
j++;
height[rank[i]] = j;
if(j > 0) j--;
}
}
}
bool ok(int len)
  {
int count=0;
 bool visit[105]= {0};
for(int i=1;i<n;i++)
 {
if(height[i]<len)
 {
if(count>0)
 {
count=0;
memset(visit,0,sizeof(visit));
}
}
else
 {
if(!visit[belong[sa[i-1]]])
 {
visit[belong[sa[i-1]]]=1;
count++;
}
if(!visit[belong[sa[i]]])
 {
visit[belong[sa[i]]]=1;
count++;
}
if(count>=m)
return 1;
}
}
return 0;
}
int binarySearch()
  {
int l=0,r=minlen;
int mid;
while(l<r)
 {
mid=(l+r+1)>>1;
if(ok(mid))
l=mid;
else r=mid-1;
}
return l;
}
char* strrev(char * ps)
  {
int t=strlen(ps);
char tmp;
for(int i=0;i<t/2;i++)
 {
tmp=ps[i];
ps[i]=ps[t-1-i];
ps[t-1-i]=tmp;
}
return ps;
}
int main()
  {
int t,tmp,j;
scanf("%d", &t);
while(t--)
 {
scanf("%d",&m);
n=0;
minlen=INT_MAX;
for(int i=0;i<m;i++)
 {
scanf("%s",str);
tmp=strlen(str);
if(tmp<minlen)
minlen=tmp;

j=n;

strcpy(s+n,str);
n+=tmp;
s[n++]='z'+i+1;

strrev(str);
strcpy(s+n,str);
n+=tmp;

s[n++]='z'+i+1;

for(;j<n;j++)
belong[j]=i;

}
s[n]='$';
suffixArray();
printf("%d\n",binarySearch());
}
return 0;
}
|