SPOJ-1811. Longest Common Substr

作者: AmadeusChan | 来源:发表于2019-02-16 20:05 被阅读0次

    题目:

    http://www.spoj.com/problems/LCS/

    http://www.spoj.com/problems/LCS2/

    两道水题,据说SA之类的常数卡得挺紧的,于是乎顺手拿过来练手了一下SAM。。。

    代码:

    1811:

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
     
    using namespace std ;
     
    #define C( t , x ) sam[ t ].ch[ x ]
    #define P( t ) sam[ t ].parent
    #define L( t ) sam[ t ].len
    #define N( t ) sam[ t ]
     
    #define check( ch ) ( ch >= 'a' && ch <= 'z' )
    #define rep( i , x ) for ( int i = 0 ; i ++ < x ; )
     
    const int maxn = 251000 ;
    const int maxv = maxn << 1 ;
     
    struct node {
            int ch[ 26 ] , parent , len ;
            node(  ) {
                   memset( ch , 0 , sizeof( ch ) ) ;
                   parent = len = 0 ; 
            }
    } sam[ maxv ] ;
     
    int root = maxv - 1 , V = 0 , last = maxv - 1 ; 
     
    void add( int ch , int l ) {
            int p = last , np = ++ V ; 
            L( np ) = l ;
            for ( ; ! C( p , ch ) && p ; p = P( p ) ) C( p , ch ) = np ;
            if ( ! p ) P( np ) = root ; else {
                   int q = C( p , ch ) ;
                   if ( L( q ) == L( p ) + 1 ) P( np ) = q ; else {
                           int r = ++ V ;
                           N( r ) = N( q ) ;
                           L( r ) = L( p ) + 1 ; 
                           P( np ) = P( q ) = r ; 
                           for ( ; p && C( p , ch ) == q ; p = P( p ) ) C( p , ch ) = r ; 
                   }
            }
            last = np ;
    }
     
    int s[ maxn ] , slen ;
     
    void getstr(  ) {
            slen = 0 ; 
            int ch ; for ( ch = getchar(  ) ; ! check( ch ) ; ch = getchar(  ) ) ; 
            s[ ++ slen ] = ch - 'a' ;
            for ( ch = getchar(  ) ; check( ch ) ; ch = getchar(  ) ) {
                   s[ ++ slen ] = ch - 'a' ;
            }
    }
     
    int main(  ) {
            getstr(  ) ;
            rep( i , slen ) add( s[ i ] , i ) ;
            int mlen = 0 , ans = 0 , t = root ;
            getstr(  ) ;
            rep( i , slen ) {
                   int ch = s[ i ] ;
                   if ( C( t , ch ) ) ++ mlen , t = C( t , ch ) ; else {
                           for ( ; t && ! C( t , ch ) ; t = P( t ) ) ;
                           if ( ! t ) t = root , mlen = 0 ; else {
                                   mlen = L( t ) + 1 ;
                                   t = C( t , ch ) ;
                           }
                   }
                   ans = max( ans , mlen ) ;
            }
            printf( "%d\n" , ans ) ;
            return 0 ; 
    }
    

    1812:

    #include <cstdio>
    
    #include <algorithm>
    
    #include <cstring>
    
     
    
    using namespace std ;
    
     
    
    #define P( t ) sam[ t ].parent
    
    #define C( t , x ) sam[ t ].child[ x ]
    
    #define N( t ) sam[ t ]
    
    #define F( t ) sam[ t ].fun
    
    #define L( t ) sam[ t ].maxlen
    
     
    
    const int maxn = 100100 ;
    
    const int maxv = maxn << 1 ; 
    
     
    
    struct node {
    
            int child[ 26 ] , parent , fun , maxlen ;
    
            node(  ) {
    
                   memset( child , 0 , sizeof( child ) ) ;
    
                   parent = fun = maxlen = 0 ; 
    
            }
    
    } sam[ maxv ] ;
    
     
    
    int last = maxv - 1 , root = maxv - 1 , V = 0 ; 
    
     
    
    void extend( int ch ) {
    
            int np = ++ V , p = last ; 
    
            L( np ) = L( p ) + 1 ; 
    
            for ( ; p && ! C( p , ch ) ; p = P( p ) ) C( p , ch ) = np ; 
    
            if ( ! p ) P( np ) = root ; else {
    
                   int q = C( p , ch ) ;
    
                   if ( L( q ) == L( p ) + 1 ) P( np ) = q ; else {
    
                           int r = ++ V ;
    
                           N( r ) = N( q ) ; 
    
                           L( r ) = L( p ) + 1 ;
    
                           P( np ) = P( q ) = r ; 
    
                           for ( ; p && C( p , ch ) == q ; p = P( p ) ) C( p , ch ) = r ; 
    
                   }
    
            }
    
            last = np ;
    
    }
    
     
    
    char s[ maxn ] ;
    
    int dp[ maxv ] , len ;
    
     
    
    void update( int &x , int val ) {
    
            x = max( x , val ) ;
    
    }
    
     
    
    int main(  ) {
    
            scanf( "%s" , s + 1 ) ;
    
            len = strlen( s + 1 ) ;
    
            for ( int i = 0 ; i ++ < len ; ) extend( s[ i ] - 'a' ) ;
    
            for ( int i = 0 ; i <= V ; ++ i ) dp[ i ] = L( i ) ;
    
            while ( scanf( "%s" , s + 1 ) != EOF ) {
    
                   len = strlen( s + 1 ) ;
    
                   for ( int i = 0 ; i <= V ; ++ i ) F( i ) = 0 ; 
    
                   for ( int i = 1 , temp = 0 , t = root ; i <= len ; ++ i ) {
    
                           int ch = s[ i ] - 'a' ;
    
                           if ( C( t , ch ) ) update( F( t = C( t , ch ) ) , ++ temp ) ; else {
    
                                   for ( ; t && ! C( t , ch ) ; t = P( t ) ) ;
    
                                   if ( ! t ) t = root , temp = 0 ; else {
    
                                          temp = L( t ) + 1 ; 
    
                                          update( F( t = C( t , ch ) ) , temp ) ;
    
                                   }
    
                           }
    
                   }
    
                   for ( int i = V ; i ; -- i ) update( F( P( i ) ) , F( i ) ) ;
    
                   for ( int i = 0 ; i <= V ; ++ i ) dp[ i ] = min( dp[ i ] , F( i ) ) ;
    
            }
    
            int ans = 0 ; 
    
            for ( int i = 0 ; i <= V ; ++ i ) update( ans , dp[ i ] ) ;
    
            printf( "%d\n" , ans ) ;
    
            return 0 ; 
    
    }
    

    相关文章

      网友评论

        本文标题:SPOJ-1811. Longest Common Substr

        本文链接:https://www.haomeiwen.com/subject/afvieqtx.html