码迷,mamicode.com
首页 > 其他好文 > 详细

LA 4513

时间:2014-11-19 21:59:06      阅读:269      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   io   ar   color   os   sp   for   

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2514

 

此题需要求在一个字符串中出现至少k次的最长子串, 如果有多个, 取rightmost的那个 , 还是用后缀数组 , 二分然后分段处理 , 不过也可以用hash解决 , 这里先给出后缀数组的代码 。   

 

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<string>
  5 #include<algorithm>
  6 
  7 const int N = 44444 ;
  8 
  9 using namespace std ;
 10 
 11 char str[N] ;
 12 int sa[N] , n , rank[N] , height[N] , t1[N] , t2[N] , c[N] , k;
 13 
 14 void build_sa( int m )
 15 {
 16      int *x = t1 , *y = t2 ;
 17      
 18      for( int i=0;i<m;i++ ) c[i] = 0 ;
 19      
 20      for( int i=0;i<n;i++ ) c[ x[i]=str[i] ] ++ ;
 21      
 22      for( int i=1;i<m;i++ ) c[i] += c[i-1] ;
 23      
 24      for( int i=n-1;i>=0;i-- ) sa[ --c[ x[i] ] ] = i ;
 25      
 26      for( int k=1;k<=n;k<<=1 ){
 27               int p = 0 ;
 28               
 29               for( int i=n-k;i<n;i++ ) y[p++] = i ;
 30               
 31               for( int i=0;i<n;i++ ) if( sa[i]>=k ) y[p++] = sa[i] - k ;
 32               
 33               for( int i=0;i<m;i++ ) c[i] = 0 ;
 34               
 35               for( int i=0;i<n;i++ ) c[ x[y[i]] ] ++ ;
 36               
 37               for( int i=1;i<m;i++ ) c[i] += c[i-1] ;
 38               
 39               for( int i=n-1;i>=0;i-- ) sa[ --c[ x[y[i]] ] ] = y[i] ;
 40               
 41               p = 1 ; swap( x , y ) ;
 42               
 43               x[ sa[0] ] = 0 ;
 44               
 45               for( int i=1;i<n;i++ )
 46                        x[ sa[i] ] = y[sa[i-1]] == y[sa[i]] && y[sa[i-1]+k]==y[sa[i]+k] ? p-1 : p++ ;    
 47                        
 48               if( p>=n ) break ;
 49               
 50               m = p ;
 51      }
 52 }
 53 
 54 void get_height()
 55 {
 56      for( int i=0;i<n;i++ ) rank[ sa[i] ] = i ;
 57      
 58      int k = 0 ;
 59      
 60      for( int i=0;i<n;i++ ){
 61               if( k ) k-- ;
 62               
 63               int j = sa[ rank[i]-1 ] ;
 64               
 65               while( str[i+k]==str[j+k] ) k ++ ;
 66               
 67               height[ rank[i] ] = k ;     
 68      }
 69      
 70      height[n] = 0 ;
 71      
 72     /* for( int i=1;i<n;i++ ){
 73               for( int j=sa[i];j<n-1;j++ )
 74                        cout<<str[j]<<" ";
 75               cout<<endl;     
 76      }*/
 77 }
 78 
 79 bool is_ok( int mid )
 80 {
 81      int pre = 1 ;
 82      
 83      for( int i=2;i<=n;i++ ){
 84               if( height[i]<mid ){
 85                                 if( i-pre>=k ) return true ; 
 86                                 pre = i ;    
 87               }     
 88      }
 89      
 90      return false ;
 91 }
 92 
 93 void print( int mid )
 94 {
 95      int pre = 1 , Max = 0 ;
 96      
 97      for( int i=2;i<=n;i++ ){
 98               if( height[i]<mid ){
 99                                 if( i-pre>=k && height[i-1]>=mid ){ 
100                                     for( int j=pre;j<i;j++ )
101                                              Max = max( Max , sa[j] ) ;
102                                 }    
103                                 pre = i ; 
104               }     
105      }
106      
107      printf("%d %d\n" , mid , Max);
108 }
109 
110 int main()
111 {
112     while( scanf("%d" , &k)!=EOF && k )
113     {
114            scanf("%s" , str) ;
115            
116            n = strlen(str) ;
117            
118            str[n] = a - 1 ;
119            
120            n++ ;
121            
122            build_sa(127) ;  get_height() ;
123            
124            int l = 0 , r = n-1 ;
125            
126            while( l<r ){
127                       if( l==r-1 ) break ; 
128                       
129                       int mid = ( l+r ) >> 1 ;
130                       
131                       if( is_ok(mid)==true )
132                                            l = mid ;
133                       else                 r = mid - 1 ;       
134            }
135            
136            if( is_ok(r)==true ) print(r) ;
137            else if( l==0 ) printf("none\n");
138            else print(l) ;
139     }
140 }

 

LA 4513

标签:style   blog   http   io   ar   color   os   sp   for   

原文地址:http://www.cnblogs.com/Crying-Smile/p/4109200.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!