题意:给出几个由小写字母构成的单词,求它们最长的公共子串的长度。
单词的数量<=5,单词的长度至少为1,最大为2000。
思路:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef unsigned int uint; 5 typedef unsigned long long ull; 6 typedef pair<int,int> PII; 7 typedef pair<ll,ll> Pll; 8 typedef vector<int> VI; 9 typedef vector<PII> VII; 10 typedef pair<ll,int>P; 11 #define N 4100 12 #define M 151000 13 #define fi first 14 #define se second 15 #define MP make_pair 16 #define pi acos(-1) 17 #define mem(a,b) memset(a,b,sizeof(a)) 18 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++) 19 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--) 20 #define lowbit(x) x&(-x) 21 #define Rand (rand()*(1<<16)+rand()) 22 #define id(x) ((x)<=B?(x):m-n/(x)+1) 23 #define ls p<<1 24 #define rs p<<1|1 25 26 const int MOD=998244353,inv2=(MOD+1)/2; 27 double eps=1e-6; 28 ll INF=1e18; 29 ll inf=5e13; 30 int dx[4]={-1,1,0,0}; 31 int dy[4]={0,0,-1,1}; 32 33 char ch[N]; 34 int n,i,x,p,q,np,nq,cnt,L,st[N],c[N][26],f[N],pos[N],bl[N],to[N],b[N],sz[N],ans[N],len[N]; 35 36 int read() 37 { 38 int v=0,f=1; 39 char c=getchar(); 40 while(c<48||57<c) {if(c=='-') f=-1; c=getchar();} 41 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 42 return v*f; 43 } 44 45 void add(int x) 46 { 47 p=np; 48 st[np=++cnt]=st[p]+1; 49 to[np]=i; 50 pos[i]=np; 51 for(;p&&!c[p][x];p=f[p]) c[p][x]=np; 52 if(!p) f[np]=1; 53 else if(st[p]+1==st[q=c[p][x]]) f[np]=q; 54 else 55 { 56 st[nq=++cnt]=st[p]+1; 57 memcpy(c[nq],c[q],sizeof c[q]); 58 f[nq]=f[q]; 59 f[q]=f[np]=nq; 60 for(;p&&c[p][x]==q;p=f[p]) c[p][x]=nq; 61 } 62 } 63 64 65 int main() 66 { 67 //freopen("1.in","r",stdin); 68 //freopen("1.out","w",stdout); 69 int cas=read(); 70 np=cnt=1; 71 scanf("%s",ch); 72 n=strlen(ch); 73 rep(i,0,n-1) add(ch[i]-'a'); 74 rep(i,1,cnt) ans[i]=st[i]; 75 rep(i,1,cnt) b[st[i]]++; 76 rep(i,1,n) b[i]+=b[i-1]; 77 rep(i,1,cnt) bl[b[st[i]]--]=i; 78 for(i=0,p=1;i<n;i++) sz[p=c[p][ch[i]-'a']]++; 79 for(i=cnt;i;i--) sz[f[bl[i]]]+=sz[bl[i]]; 80 //rep(i,0,n-1) printf("%d ",sz[pos[i]]); 81 rep(v,1,cas-1) 82 { 83 scanf("%s",ch); 84 n=strlen(ch); 85 rep(i,1,cnt) len[i]=0; 86 for(p=1,i=L=0;i<n;i++) 87 { 88 int x=ch[i]-'a'; 89 while(!c[p][x]&&p) p=f[p]; 90 if(!p) p=1,L=0; 91 else L=min(L,st[p])+1,p=c[p][x]; 92 len[p]=max(len[p],L); 93 } 94 per(i,cnt,1) len[f[bl[i]]]=max(len[f[bl[i]]],len[bl[i]]); 95 rep(i,1,cnt) ans[i]=min(ans[i],len[i]); 96 } 97 int Ans=0; 98 rep(i,1,cnt) Ans=max(Ans,ans[i]); 99 printf("%d ",Ans); 100 return 0; 101 }