Substrings POJ - 1226 (suffix array)

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 }
View Code

 

Guess you like

Origin www.cnblogs.com/iwannabe/p/11483455.html