Question meaning: Given n n strings, the longest uncoordinated strings appear at least twice for each string.
This is actually a slight change to the longest common substring of two strings. We connect all strings with different delimiters and record the subscripts of the corresponding strings of each subscript. Then we can go to dichotomize LCP, and then we can find that all suffixes of LCP (i, j)>= x must be in a continuous group. This casually writes a string and then types out the row. The suffix after the order can be seen directly.
Then, we find LCP groups satisfying >= x for each group, and then record the occurrence times of direct violence cnt in the group, maintain a Max and Min, then we can determine whether to find LCP satisfying the topic.
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define rank Rank #define inf 0x3f3f3f3f #define F(x) ((x)/3+((x)%3==1?0:tb)) #define G(x) ((x)<tb?(x)*3+1:((x)-tb)*3+2) const int maxn=1e6+500; int n,tt; char s[maxn]; int r[maxn],sa[maxn],rank[maxn],height[maxn]; int wa[maxn],wb[maxn],wv[maxn],wws[maxn]; void sort(int *r,int *a,int *b,int n,int m) { int i; for(i=0; i<n; i++) wv[i]=r[a[i]]; for(i=0; i<m; i++) wws[i]=0; for(i=0; i<n; i++) wws[wv[i]]++; for(i=1; i<m; i++) wws[i]+=wws[i-1]; for(i=n-1; i>=0; i--) b[--wws[wv[i]]]=a[i]; return; } int c0(int *r,int a,int b) { return r[a]==r[b]&&r[a+1]==r[b+1]&&r[a+2]==r[b+2]; } int c12(int k,int *r,int a,int b) { if(k==2) return r[a]<r[b]||r[a]==r[b]&&c12(1,r,a+1,b+1); else return r[a]<r[b]||r[a]==r[b]&&wv[a+1]<wv[b+1]; } void get_sa_dc3(int *r,int *sa,int n,int m) { int i,j,*rn=r+n,*san=sa+n,ta=0,tb=(n+1)/3,tbc=0,p; r[n]=r[n+1]=0; for(i=0; i<n; i++) if(i%3!=0) wa[tbc++]=i; sort(r+2,wa,wb,tbc,m); sort(r+1,wb,wa,tbc,m); sort(r,wa,wb,tbc,m); for(p=1,rn[F(wb[0])]=0,i=1; i<tbc; i++) rn[F(wb[i])]=c0(r,wb[i-1],wb[i])?p-1:p++; if(p<tbc) get_sa_dc3(rn,san,tbc,p); else for(i=0; i<tbc; i++) san[rn[i]]=i; for(i=0; i<tbc; i++) if(san[i]<tb) wb[ta++]=san[i]*3; if(n%3==1) wb[ta++]=n-1; sort(r,wb,wa,ta,m); for(i=0; i<tbc; i++) wv[wb[i]=G(san[i])]=i; for(i=0,j=0,p=0; i<ta && j<tbc; p++) sa[p]=c12(wb[j]%3,r,wa[i],wb[j])?wa[i++]:wb[j++]; for(; i<ta; p++) sa[p]=wa[i++]; for(; j<tbc; p++) sa[p]=wb[j++]; return; } void get_height(int *r, int *sa, int n) { int i, j, k = 0; for (i = 1; i <= n; ++i) rank[sa[i]] = i; for (i = 0; i < n; height[rank[i++]] = k) for (k ? k-- : 0, j = sa[rank[i] - 1]; r[i + k] == r[j + k]; ++k); return; } const int sz=20; int cnt[sz],Min[sz],Max[sz],conv[maxn]; void init() { memset(cnt,0,sizeof(cnt)); memset(Min,inf,sizeof(Min)); memset(Max,-inf,sizeof(Max)); } bool check(int x) { init(); for(int i=1,j; i<=n; i++) { if(height[i]<x) { for(j=1; j<=tt; j++) if(cnt[j]<2||Max[j]-Min[j]<x) break; if(j!=tt+1) init(); else return true; } cnt[conv[sa[i]]]++; Max[conv[sa[i]]]=max(Max[conv[sa[i]]],sa[i]); Min[conv[sa[i]]]=min(Min[conv[sa[i]]],sa[i]); // cout<<Min[conv[sa[i]]]<<" "<<Max[conv[sa[i]]]<<endl; } return false; } int main() { int t; scanf("%d",&t); while(t--) { n=0; scanf("%d",&tt); for(int i=1; i<=tt; i++) { scanf("%s",s); int len=strlen(s); for(int j=0; j<len; j++) r[n]=s[j]-'a'+129,conv[n++]=i; r[n]='z'+i-'a'+129,conv[n++]=0; } r[n]=0; get_sa_dc3(r,sa,n+1,300); get_height(r,sa,n); int L=0,R=n,mid,ans=0; while(L<=R) { mid=(L+R)>>1; if(check(mid)) ans=max(ans,mid),L=mid+1; else R=mid-1; } printf("%d\n",ans); } }