Guest User

Untitled

a guest
May 26th, 2018
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.37 KB | None | 0 0
  1. /* suffix array in O( nlongn )*/
  2.  
  3. #include<stdio.h>
  4. #include<string.h>
  5. #include<vector>
  6. #include<algorithm>
  7. using namespace std;
  8.  
  9. #define MAX 7777
  10.  
  11. struct DATA{
  12.     long Val[2];
  13.     long Ind;
  14. };
  15. // is needed if qsort is used
  16. bool operator<( const DATA &a,const DATA &b )
  17. {
  18.     if( a.Val[0] != b.Val[0] ) return a.Val[0] < b.Val[0];
  19.     else return a.Val[1] < b.Val[1];
  20. }
  21.  
  22. long Len;
  23. char Str[3*MAX+7];
  24. long Ind[14];
  25.  
  26. long Len1,Len2,Len3;
  27. char Str1[MAX+7],Str2[MAX+7],Str3[MAX+7];
  28.  
  29. long Buc[17][3*MAX+7];
  30. long SuffA[3*MAX+7];
  31. long Stp;        
  32.  
  33.  
  34. long Cnt[3*MAX+7],Cum[3*MAX+7];
  35.  
  36. void CountSort( vector<DATA> &Inf,long I )
  37. {
  38.     // max is used to count max val is used
  39.     // +1 adding is needed to handle -1
  40.     long i,Max = 0;
  41.     for( i=0;i<Inf.size();i++){
  42.         if( Max < Inf[i].Val[I] + 1 ) Max = Inf[i].Val[I] + 1;
  43.     }
  44.  
  45.     memset( Cnt,0,(Max+1)*sizeof(long));
  46.     for( i=0;i<Inf.size();i++){
  47.         Cnt[Inf[i].Val[I] + 1 ]++;
  48.     }
  49.  
  50.     Cum[0] = Cnt[0];
  51.     for( i=1;i<=Max;i++){
  52.         Cum[i] = Cum[i-1] + Cnt[i];
  53.     }
  54.  
  55.     vector<DATA> Tmp;
  56.     Tmp.resize( Inf.size());
  57.     for( i=Inf.size()-1;i>=0;i--){
  58.         Cum[ Inf[i].Val[I] + 1 ]--;
  59.         Tmp[ Cum[ Inf[i].Val[I] +1 ] ] = Inf[i];
  60.        
  61.     }
  62.     Inf = Tmp;
  63. }
  64.  
  65.  
  66. void SuffArrCreate( void )
  67. {
  68.     long i,j;
  69.  
  70.     for( i=0;i<Len;i++){
  71.         Buc[0][i] = Str[i];
  72.     }
  73.     vector<DATA> Inf;
  74.     Inf.resize( Len );
  75.     long c;
  76.     for( c=1,Stp=1;c < Len;c<<=1,Stp++ ){
  77.  
  78.         for( j=0;j<Len;j++){
  79.             Inf[j].Val[0] = Buc[Stp-1][j];
  80.             Inf[j].Val[1] = j+c < Len ? Buc[Stp-1][j+c]:-1;
  81.             Inf[j].Ind = j;
  82.         }
  83.         // if O( nlogn^2 ) pos
  84.         //sort( Inf.begin(),Inf.end());
  85.         CountSort( Inf , 1 );
  86.         CountSort( Inf , 0 );
  87.  
  88.         Buc[Stp][Inf[0].Ind] = 0;
  89.         for( j=1;j<Inf.size();j++){
  90.             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];
  91.             else{
  92.                 Buc[Stp][Inf[j].Ind] = j;
  93.             }
  94.         }
  95.     }
  96.     Stp--;
  97.     for( i=0;i<Len;i++){
  98.         SuffA[Buc[Stp][i]] = i;
  99.     }
  100.  
  101. }
  102. // fining longest common pref lenth of two suffix in O(longn)
  103. long Lcp( long i,long j )
  104. {
  105.     long k,Tot = 0;
  106.     for( k=Stp;k>=0 && i<Len && j<Len;k--){
  107.         if( Buc[k][i]==Buc[k][j] ){
  108.             i += 1<<k;
  109.             j += 1<<k;
  110.             Tot += 1<<k;
  111.         }
  112.     }
  113.     return Tot;
  114. }
  115.  
  116. inline long max( long a,long b )
  117. {
  118.     return a>b ? a:b;
  119. }
  120.  
  121. inline long min( long a,long b )
  122. {
  123.     return a<b ? a:b;
  124. }
  125.  
  126.  
  127. inline long Who( long l )
  128. {
  129.     if( l<Len1 ) return 1;
  130.     else if( l<Len2 ) return 2;
  131.     else if( l<Len3 ) return 3;
  132. }
  133.  
  134.  
  135. long CheckLCP( void )
  136. {
  137.     if( Ind[1]==-1 || Ind[2]==-1 || Ind[3]==-1 ) return 0;
  138.     long c1 = Lcp( Ind[1],Ind[2] );
  139.     c1 = min( c1,min( Len1-Ind[1],Len2-Ind[2] ));
  140.     long c2 = Lcp( Ind[2],Ind[3] );
  141.     c2 = min( c2,min( Len2-Ind[2],Len3-Ind[3] ));
  142.     long c3 = Lcp( Ind[1],Ind[3] );
  143.     c3 = min( c3,min( Len1-Ind[1],Len3-Ind[3] ));
  144.     return min( c1,min( c2,c3 ));
  145. }
  146.  
  147.  
  148. int main( void )
  149. {
  150.     long i,Icase,k = 0;
  151.  
  152.     //freopen("text1.txt","r",stdin );
  153.  
  154.     scanf("%ld",&Icase );
  155.     while( Icase-- ){
  156.         scanf("%s",Str1 );
  157.         Len1 = strlen( Str1 );
  158.         scanf("%s",Str2 );
  159.         Len2 = Len1+strlen( Str2 );
  160.         scanf("%s",Str3 );
  161.         Len3 = Len2+strlen( Str3 );
  162.  
  163.         strcpy( Str,Str1 );
  164.         strcat( Str,Str2 );
  165.         strcat( Str,Str3 );
  166.         Len = strlen(Str);
  167.  
  168.         SuffArrCreate();
  169.         memset( Ind,-1,sizeof(Ind));
  170.         long Ans = 0;
  171.         for( i=0;i<Len;i++){
  172.             long w = Who( SuffA[i] );
  173.             Ind[w] = SuffA[i];
  174.             Ans = max( Ans,CheckLCP());
  175.         }
  176.         printf("Case %ld: %ld\n",++k,Ans );
  177.     }
  178.  
  179.     return 0;
  180. }
Add Comment
Please, Sign In to add comment