Description
Solution
有一个很显然的性质:如果a是吧的子串,b是c的子串,那么a一定是c的子串,
所以我们开一个栈,从后往前做,如当前串为栈顶子串就加入栈,否则就记录ans并弹出栈顶。
复杂度: O(Tnm)(m为串长)
Code
#include <iostream>
#include <cstdio>
#include <cstdlib>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int N=501,M=2002;
int n,m,ans,b0;
int a[N][M];
int nx[N][M];
int za[N];
bool OK(int Q,int W)
{
if(a[Q][0]<a[W][0])return 0;
int q=0;
fo(i,1,a[Q][0])
{
while(q&&a[Q][i]!=a[W][q+1])q=nx[W][q];
if(a[Q][i]==a[W][q+1])q++;
if(q>=a[W][0])return 1;
}
return q>=a[W][0];
}
int main()
{
freopen("sub.in","r",stdin);
freopen("sub.out","w",stdout);
int q,w,_;
scanf("%d",&_);
while(_--)
{
scanf("%d",&n);
fo(i,1,n)
{
char ch;a[i][0]=0;
for(ch=getchar();ch<'a'||ch>'z';ch=getchar());
for(;ch<='z'&&'a'<=ch;ch=getchar())a[i][++a[i][0]]=ch-97;
}
fo(i,1,n)
{
q=0;
fo(j,2,n)
{
while(q&&a[i][q+1]!=a[i][j])q=nx[i][q];
if(a[i][q+1]==a[i][j])q++;
nx[i][j]=q;
}
}
za[za[0]=1]=n;
ans=-1;
fod(i,n-1,1)
{
while(za[0]&&!OK(za[za[0]],i))
{
ans=max(ans,za[za[0]]);
za[0]--;
}
za[++za[0]]=i;
}
printf("%d\n",ans);
}
return 0;
}