【JZOJ 4910】子串

来源:互联网 发布:淘宝药店 提交需求 编辑:程序博客网 时间:2024/06/11 00:01

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;}
0 0