You are given a number of case-sensitive strings of alphabetic characters, find the largest string X, such that either X, or its inverse can be found as a substring of any of the given strings.
Input
The first line of the input contains a single integer t (1 <= t <= 10), the number of test cases, followed by the input data for each test case. The first line of each test case contains a single integer n (1 <= n <= 100), the number of given strings, followed by n lines, each representing one string of minimum length 1 and maximum length 100. There is no extra white space before and after a string.
Output
There should be one line per test case containing the length of the largest string found.
Sample Input
2 3 ABCD BCDFF BRCD 2 rose orchid
Sample Output
2 2
that Italy: Determine all string, the length of the longest substring (not necessarily equal to the substring, the substring is also equal to the line inversion)
ideas: two molecules of the string length, each combined into strings and playing thereof an array and then seek suffix array, and record each string length and prefix (prefix length and refer to adding the string and its length after playing the entire character)
and then for ht array, if the current corresponding to the array ht [i sa sa] and [i-1] has not been so before the occurrence of the string, then the number of + 1 type, until the number of types == n
if she find the recorded information before ht <mid then emptied, again matching
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 using namespace std; 7 8 int T,n; 9 const int maxn = 2e5+5; 10 string s; 11 int sa[maxn],t[maxn],t2[maxn],c[maxn],len[105]; 12 13 void build_sa(int n,int m) 14 { 15 int i,*x=t,*y=t2; 16 for(i=0; i<m; i++)c[i]=0; 17 for(i=0; i<n; i++)c[x[i]=s[i]]++; 18 for(i=1; i<m; i++)c[i]+=c[i-1]; 19 for(i=n-1; i>=0; i--)sa[--c[x[i]]]=i; 20 for(int k=1; k<=n; k<<=1) 21 { 22 int p=0; 23 for(i=n-k; i<n; i++)y[p++]=i; 24 for(i=0; i<n; i++)if(sa[i] >= k)y[p++]=sa[i]-k; 25 for(i=0; i<m; i++)c[i] = 0; 26 for(i=0; i<n; i++)c[x[y[i]]]++; 27 for(i=1; i<m; i++)c[i]+=c[i-1]; 28 for(i=n-1; i>=0; i--)sa[--c[x[y[i]]]] = y[i]; 29 swap(x,y); 30 p=1,x[sa[0]]=0; 31 for(i=1; i<n; i++) 32 x[sa[i]] = y[sa[i-1]] == y[sa[i]] && y[sa[i-1]+k] == y[sa[i]+k]?p-1:p++; 33 if(p>=n)break; 34 m=p; 35 } 36 } 37 38 int ht[maxn],rk[maxn]; 39 40 void getHeight(int n) 41 { 42 int i,j,k=0; 43 for(i=0; i<n; i++)rk[sa[i]] = i; 44 for(i=0; i<n-1; i++) 45 { 46 if(k)k--; 47 if(s[i] == '$')continue; 48 int j = sa[rk[i]-1]; 49 while(s[i+k] == s[j+k] && s[i+k] != '$')k++; 50 ht[rk[i]] = k; 51 } 52 } 53 54 bool vis[105]; 55 bool check(int mid) 56 { 57 memset(vis,0,sizeof(vis)); 58 int cnt=0; 59 bool flag = 0; 60 for(int i=1; i<len[n]; i++) 61 { 62 if(ht[i] >= mid && s[sa[i]] != '$') 63 { 64 65 for(int j=1; j<=n; j++) 66 { 67 if(!flag) 68 { 69 //printf("%d $$$$ %d %d\n",sa[i-1]+1,len[j-1],len[j]); 70 if(sa[i-1]+1 > len[j-1] && sa[i-1]+1 < len[j])if(!vis[j])vis[j]=1,cnt++,flag = 1; 71 } 72 if(sa[i]+1 > len[j-1] && sa[i]+1 < len[j])if(!vis[j])vis[j] = 1,cnt++; 73 } 74 // printf("============================================\n",flag); 75 } 76 else 77 { 78 if(cnt == n)return 1; 79 cnt = 0; 80 flag = 0; 81 memset(vis,0,sizeof(vis)); 82 } 83 } 84 if(cnt == n)return 1; 85 return 0; 86 } 87 char tmp[200]; 88 int main() 89 { 90 scanf("%d",&T); 91 while(T--) 92 { 93 scanf("%d",&n); 94 s.clear(); 95 for(int i=1; i<=n; i++) 96 { 97 scanf("%s",tmp); 98 int tmp_len = strlen(tmp); 99 s+=tmp; 100 s+='$'; 101 reverse(tmp,tmp+tmp_len); 102 s+=tmp; 103 s+='$'; 104 len[i] = s.length(); 105 } 106 // for(int i=1;i<=n;i++)printf("%d =========\n",len[i]); 107 // if(n == 1) 108 // { 109 // printf("%d\n",len[1]/2-1); 110 // continue; 111 // } 112 build_sa(len[n],130); 113 getHeight(len[n]); 114 int L = 1,R = len[n]; 115 int pos = 0; 116 while(L <= R) 117 { 118 int mid = (L+R)/2; 119 if(check(mid))pos = mid,L=mid+1; 120 else R = mid-1; 121 } 122 cout << pos << endl; 123 } 124 125 }