"topic link" http://poj.org/problem?id=3080
"The main topic"
The longest common substring of k-strings, if there are more than one, the output dictionary order is the smallest, if the length is less than 3 to determine the failure of the lookup.
Exercises
Put all the strings through the concatenation of a string, do the suffix array, the second answer, for the binary value, the H array is larger than the value of the adjacent elements into a group, determine whether the group of elements covered in the whole dictionary, is the answer, for the answer Scan SA, output the first scan to the substring.
Code
#include <cstdio> #include <cstring> #include <vector> #include <algorithm>using namespace std; const int N=2000010;int n,m,rank[n],sa[n],h[n],tmp[n],cnt[n],ans,a[n],s[n]; Char str[n];void suffixarray (int n,int m) {int i,j,k;n++; for (i=0;i<2*n+5;i++) rank[i]=sa[i]=h[i]=tmp[i]=0; for (i=0;i<m;i++) cnt[i]=0; for (i=0;i<n;i++) cnt[rank[i]=s[i]]++; for (i=1;i<m;i++) cnt[i]+=cnt[i-1]; for (i=0;i<n;i++) sa[--cnt[rank[i]]]=i; for (K=1;k<=n;k<<=1) {for (i=0;i<n;i++) {j=sa[i]-k; if (j<0) j+=n; Tmp[cnt[rank[j]]++]=j; }sa[tmp[cnt[0]=0]]=j=0; for (i=1;i<n;i++) {if (rank[tmp[i]]!=rank[tmp[i-1]]| | RANK[TMP[I]+K]!=RANK[TMP[I-1]+K]) cnt[++j]=i; Sa[tmp[i]]=j; }memcpy (rank,sa,n*sizeof (int)); memcpy (sa,tmp,n*sizeof (int)); if (j>=n-1) break; }for (j=rank[h[i=k=0]=0];i<n-1;i++,k++) while (~k&&s[i]!=s[sa[j-1]+k]) h[j]=k--, j=rank[sa[j]+1];} InchT len[n],u,k;vector<int> s[n];bool vis[4010];bool Check (int L) {int cur=-1; for (int i=1;i<=u;i++) {if (h[i]<l) s[++cur].clear (); S[cur].push_back (i); } for (int i=0;i<=cur;i++) {if (S[i].size () >=n) {memset (vis,0,sizeof (VIS)); for (int j=0;j<s[i].size (); j + +) {int k=s[i][j]; int X=upper_bound (A,A+N+1,SA[S[I][J]])-a-1; Vis[x]=1; }int count=0; for (int j=0;j<n;j++) if (vis[j]) count++; if (count>=n) return 1; }}return 0;} void Print (int L) {int cur=-1; for (int i=1;i<=u;i++) {if (h[i]<l) s[++cur].clear (); S[cur].push_back (i); } for (int i=0;i<=cur;i++) {if (S[i].size () >=n) {memset (vis,0,sizeof (VIS)); for (int j=0;j<s[i].size (); j + +) {int k=s[i][j]; int X=upper_bound (A,A+N+1,SA[S[I][J]])-a-1; Vis[x]=true; }int count=0; for (int j=0;j<n;j++) if (vis[j]) count++; if (count>=n) {for (int j=0;j<l;j++) printf ("%c", char (S[sa[s[i][0]]+j])); Puts (""); Return }}}}int T;int main () {scanf ("%d", &t); while (t--) {scanf ("%d", &n); int tmp=200; u=0; for (int i=0;i<n;i++) {scanf ("%s", str); Len[i]=strlen (str); for (int j=0;j<len[i];j++) s[u++]= (int) str[j]; s[u++]=tmp++; }tmp=0; s[u]=0; for (int i=0;i<=n;i++) {a[i]=tmp; if (i<n) tmp=tmp+ (i==0?len[i]:len[i]+1); }suffixarray (u,5000); int l=1,r=len[n-1],ans=0; while (l<=r) {int mid= (L+R) >>1; if (check (mid)) ans=mid,l=mid+1; else r=mid-1; }if (ans<3) puts ("no significant commonalities"); Else Print (ans); }return 0;}
POJ 3080 Blue Jeans (suffix array + two-point answer)