Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* suffix array in O( nlongn )*/
- #include<stdio.h>
- #include<string.h>
- #include<vector>
- #include<algorithm>
- using namespace std;
- #define MAX 7777
- struct DATA{
- long Val[2];
- long Ind;
- };
- // is needed if qsort is used
- bool operator<( const DATA &a,const DATA &b )
- {
- if( a.Val[0] != b.Val[0] ) return a.Val[0] < b.Val[0];
- else return a.Val[1] < b.Val[1];
- }
- long Len;
- char Str[3*MAX+7];
- long Ind[14];
- long Len1,Len2,Len3;
- char Str1[MAX+7],Str2[MAX+7],Str3[MAX+7];
- long Buc[17][3*MAX+7];
- long SuffA[3*MAX+7];
- long Stp;
- long Cnt[3*MAX+7],Cum[3*MAX+7];
- void CountSort( vector<DATA> &Inf,long I )
- {
- // max is used to count max val is used
- // +1 adding is needed to handle -1
- long i,Max = 0;
- for( i=0;i<Inf.size();i++){
- if( Max < Inf[i].Val[I] + 1 ) Max = Inf[i].Val[I] + 1;
- }
- memset( Cnt,0,(Max+1)*sizeof(long));
- for( i=0;i<Inf.size();i++){
- Cnt[Inf[i].Val[I] + 1 ]++;
- }
- Cum[0] = Cnt[0];
- for( i=1;i<=Max;i++){
- Cum[i] = Cum[i-1] + Cnt[i];
- }
- vector<DATA> Tmp;
- Tmp.resize( Inf.size());
- for( i=Inf.size()-1;i>=0;i--){
- Cum[ Inf[i].Val[I] + 1 ]--;
- Tmp[ Cum[ Inf[i].Val[I] +1 ] ] = Inf[i];
- }
- Inf = Tmp;
- }
- void SuffArrCreate( void )
- {
- long i,j;
- for( i=0;i<Len;i++){
- Buc[0][i] = Str[i];
- }
- vector<DATA> Inf;
- Inf.resize( Len );
- long c;
- for( c=1,Stp=1;c < Len;c<<=1,Stp++ ){
- for( j=0;j<Len;j++){
- Inf[j].Val[0] = Buc[Stp-1][j];
- Inf[j].Val[1] = j+c < Len ? Buc[Stp-1][j+c]:-1;
- Inf[j].Ind = j;
- }
- // if O( nlogn^2 ) pos
- //sort( Inf.begin(),Inf.end());
- CountSort( Inf , 1 );
- CountSort( Inf , 0 );
- Buc[Stp][Inf[0].Ind] = 0;
- for( j=1;j<Inf.size();j++){
- if( Inf[j].Val[0]==Inf[j-1].Val[0] && Inf[j].Val[1]==Inf[j-1].Val[1] ) Buc[Stp][Inf[j].Ind] = Buc[Stp][Inf[j-1].Ind];
- else{
- Buc[Stp][Inf[j].Ind] = j;
- }
- }
- }
- Stp--;
- for( i=0;i<Len;i++){
- SuffA[Buc[Stp][i]] = i;
- }
- }
- // fining longest common pref lenth of two suffix in O(longn)
- long Lcp( long i,long j )
- {
- long k,Tot = 0;
- for( k=Stp;k>=0 && i<Len && j<Len;k--){
- if( Buc[k][i]==Buc[k][j] ){
- i += 1<<k;
- j += 1<<k;
- Tot += 1<<k;
- }
- }
- return Tot;
- }
- inline long max( long a,long b )
- {
- return a>b ? a:b;
- }
- inline long min( long a,long b )
- {
- return a<b ? a:b;
- }
- inline long Who( long l )
- {
- if( l<Len1 ) return 1;
- else if( l<Len2 ) return 2;
- else if( l<Len3 ) return 3;
- }
- long CheckLCP( void )
- {
- if( Ind[1]==-1 || Ind[2]==-1 || Ind[3]==-1 ) return 0;
- long c1 = Lcp( Ind[1],Ind[2] );
- c1 = min( c1,min( Len1-Ind[1],Len2-Ind[2] ));
- long c2 = Lcp( Ind[2],Ind[3] );
- c2 = min( c2,min( Len2-Ind[2],Len3-Ind[3] ));
- long c3 = Lcp( Ind[1],Ind[3] );
- c3 = min( c3,min( Len1-Ind[1],Len3-Ind[3] ));
- return min( c1,min( c2,c3 ));
- }
- int main( void )
- {
- long i,Icase,k = 0;
- //freopen("text1.txt","r",stdin );
- scanf("%ld",&Icase );
- while( Icase-- ){
- scanf("%s",Str1 );
- Len1 = strlen( Str1 );
- scanf("%s",Str2 );
- Len2 = Len1+strlen( Str2 );
- scanf("%s",Str3 );
- Len3 = Len2+strlen( Str3 );
- strcpy( Str,Str1 );
- strcat( Str,Str2 );
- strcat( Str,Str3 );
- Len = strlen(Str);
- SuffArrCreate();
- memset( Ind,-1,sizeof(Ind));
- long Ans = 0;
- for( i=0;i<Len;i++){
- long w = Who( SuffA[i] );
- Ind[w] = SuffA[i];
- Ans = max( Ans,CheckLCP());
- }
- printf("Case %ld: %ld\n",++k,Ans );
- }
- return 0;
- }
Add Comment
Please, Sign In to add comment