BZOJ-2105: 增强型LCP(HASH+SBT)

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2105

CQF原题:http://wenku.baidu.com/view/1741543f5727a5e9856a6108.html

这道题网上的代码基本都是块状链表的,据说写SPLAY会T得很惨,然后我就各种DT地写了SBT,一交上去,TLE,然后回过头了,开始了漫长的常数优化,平衡化建树神马的都用上了,终于让我给卡过去了。。。

代码(在巨慢无比的时耗之后巨长无比的代码):


63d0f703918fa0ec7beceb57249759ee3d6ddb45.jpg.png
#include 

#include 

#include 

  

using namespace std ;

  

#define L( t ) left[ t ]

#define R( t ) right[ t ]

#define S( t ) size[ t ]

#define V( t ) value[ t ]

#define H( t ) Hash[ t ]

#define MAXN 201000

#define ULL int

#define MAX 29

#define clear( x ) memset( x , 0 , sizeof( x ) )

#define check( ch ) ( ch >= 'A' && ch <= 'Z' )

  

int left[ MAXN ] , right[ MAXN ] , V = 0 , roof = 0 ;

ULL value[ MAXN ] , Hash[ MAXN ] , Exp[ MAXN ] , size[ MAXN ] ;

  

void update( int t ) {

    S( t ) = S( L( t ) ) + S( R( t ) ) + 1 ;

    H( t ) = H( R( t ) ) + Exp[ S( R( t ) ) ] * V( t ) + Exp[ S( R( t ) ) + 1 ] * H( L( t ) ) ;

}

  

void Left( int &t ) {

    int k = R( t ) ;

    R( t ) = L( k ) ; update( t ) ;

    L( k ) = t ; update( k ) ;

    t = k ;

}

  

void Right( int &t ) {

    int k = L( t ) ;

    L( t ) = R( k ) ;update( t ) ;

    R( k ) = t ; update( k ) ;

    t = k ;

}

  

void maintain( int &t ) {

    if ( S( L( L( t ) ) ) > S( R( t ) ) ) {

        Right( t ) ;

        maintain( R( t ) ) ; maintain( t ) ;

        return ;

    }

    if ( S( R( L( t ) ) ) > S( R( t ) ) ) {

        Left( L( t ) ) ; Right( t ) ;

        maintain( L( t ) ) , maintain( R( t ) ) ; maintain( t ) ;

        return ;

    }

    if ( S( R( R( t ) ) ) > S( L( t ) ) ) {

        Left( t ) ;

        maintain( L( t ) ) ; maintain( t ) ;

        return ;

    }

    if ( S( L( R( t ) ) ) > S( L( t ) ) ) {

        Right( R( t ) ) ; Left( t ) ;

        maintain( L( t ) ) , maintain( R( t ) ) ; maintain( t ) ;

        return ;

    }

}

  

void Insert( int s , int u , int &t ) {

    if ( ! t ) {

        t = u ; return ;

    }

    if ( S( L( t ) ) >= s ) Insert( s , u , L( t ) ) ; else

    Insert( s - S( L( t ) ) - 1 , u , R( t ) ) ;

    update( t ) ; maintain( t ) ;

}

  

void Delete( int s , int &t ) {

    if ( s == S( L( t ) ) ) {

        if ( ! L( t ) ) {

            t = R( t ) ; return ;

        } else if ( ! R( t ) ) {

            t = L( t ) ; return ;

        } else {

            Right( t ) ; Delete( S( L( R( t ) ) ) , R( t ) ) ;

        }

    } else if ( s < S( L( t ) ) ) Delete( s , L( t ) ) ; else

    Delete( s - S( L( t ) ) - 1 , R( t ) ) ;

    update( t ) ; maintain( t ) ;

}

  

ULL Query( ULL l , ULL r , int t ) {

    if ( ! l && r == S( t ) - 1 ) return H( t ) ;

    if ( r < S( L( t ) ) ) return Query( l , r , L( t ) ) ;

    if ( l > S( L( t ) ) ) return Query( l - S( L( t ) ) - 1 , r - S( L( t ) ) - 1 , R( t ) ) ;

    if ( l == S( L( t ) ) && r == S( L( t ) ) ) return V( t ) ;

    if ( r == S( L( t ) ) ) {

        return Query( l , r - 1 , L( t ) ) * Exp[ 1 ] + V( t ) ;

    } else if ( l == S( L( t ) ) ) {

        return V( t ) * Exp[ r - l ] + Query( 0 , r - S( L( t ) ) - 1 , R( t ) ) ;

    } else {

        ULL x = Query( l , S( L( t ) ) - 1 , L( t ) ) ;

        ULL y = Query( 0 , r - S( L( t ) ) - 1 , R( t ) ) ;

        return x * Exp[ r - S( L( t ) ) + 1 ] + V( t ) * Exp[ r - S( L( t ) ) ] + y ;

    }

}

  

void create( char c , int t ) {

    S( t ) = 1 , V( t ) = H( t ) = c ;

    return ;

}

  

void INIT(  ) {

    clear( left ) , clear( right ) , clear( size ) ;

    clear( value ) , clear( Hash ) , clear( Exp ) ;

    Exp[ 0 ] = 1 ;

    for ( int i = 0 ; i ++ < MAXN - 1 ; ) Exp[ i ] = Exp[ i - 1 ] * MAX ;

}

  

char s[ MAXN ] ;

int n , m ;

  

int Solve( int x , int y ) {

    int l = 0 , r = min( S( roof ) - x + 1 , S( roof ) - y + 1 ) + 1 ;

    int lastmid = 0x7fffffff ;

    ULL lastrec , lastret ;

    while ( r - l > 1 ) {

        int mid = ( l + r ) >> 1 ;

        ULL rec , ret ;

        if ( lastmid < mid ) {

            rec = Query( x + lastmid - 1 , x + mid - 2 , roof ) ;

            ret = Query( y + lastmid - 1 , y + mid - 2 , roof ) ;

            rec = lastrec * Exp[ mid - lastmid ] + rec ;

            ret = lastret * Exp[ mid - lastmid ] + ret ;

        } else {

            rec = Query( x - 1 , x + mid - 2 , roof ) ;

            ret = Query( y - 1 , y + mid - 2 , roof ) ;

        }

        if ( rec == ret ) {

            l = mid ;

        } else r = mid ;

        lastmid = mid ;

        lastrec = rec , lastret = ret ;

    }

    return l ;

}

  

int getstr( char *ss ) {

    int ch , len = 0 ;

    for ( ch = getchar(  ) ; ch == ' ' || ch == '\n' || ch == EOF ; ch = getchar(  ) ) ;

    ss[ len ++ ] = ch ;

    for ( ch = getchar(  ) ; ch != ' ' && ch != '\n' && ch != EOF ; ch = getchar(  ) ) ss[ len ++ ] = ch ;

    return len ;

}

  

void getint( int &t ) {

    int ch ; for ( ch = getchar(  ) ; ! ( ch >= '0' && ch <= '9' ) ; ch = getchar(  ) ) ;

    t = ch - '0' ;

    for ( ch = getchar(  ) ; ch >= '0' && ch <= '9' ; ch = getchar(  ) ) {

        t *= 10 , t += ch - '0' ;

    }

}

 

int out[ 20 ] ;

 

void putint( int t ) {

    if ( ! t ) putchar( '0' ) ; else {

        out[ 0 ] = 0 ;

        for ( ; t ; t /= 10 ) out[ ++ out[ 0 ] ] = t % 10 ;

        while ( out[ 0 ] -- ) putchar( '0' + out[ out[ 0 ] + 1 ] ) ;

    }

    putchar( '\n' ) ;

}

 

void build( int l , int r , int &t , char *s ) {

    t = ++ V ;

    int mid = ( l + r ) >> 1 ;

    V( t ) = s[ mid ] , S( t ) = 1 ;

    if ( l <= mid - 1 ) build( l , mid - 1 , L( t ) , s ) ;

    if ( r >= mid + 1 ) build( mid + 1 , r , R( t ) , s ) ;

    update( t ) ;

}

 

void CHANGE( int l , int r , int l0 , int r0 , char *s , int t ) {

    if ( r < S( L( t ) ) ) CHANGE( l , r , l0 , r0 , s , L( t ) ) ; else

    if ( l > S( L( t ) ) ) CHANGE( l - S( L( t ) ) - 1 , r - S( L( t ) ) - 1 , l0 , r0 , s , R( t ) ) ; else {

        int L = S( L( t ) ) - l ;

        int R = r - l - L ;

        V( t ) = s[ l0 + L ] ;

        if ( L ) CHANGE( l , S( L( t ) ) - 1 , l0 , l0 + L - 1 , s , L( t ) ) ;

        if ( R ) CHANGE( 0 , r - S( L( t ) ) - 1 , r0 - R + 1 , r0 , s , R( t ) ) ;

    }

    update( t ) ;

     

}

 

int main(  ) {

    INIT(  ) ;

    getint( n ) , getint( m ) ;

    getstr( s ) ;

    build( 0 , n - 1 , roof , s ) ;

    while ( m -- ) {

        int ch ; for ( ch = getchar(  ) ; ! check( ch ) ; ch = getchar(  ) ) ;

        if ( ch == 'L' ) {

            int a , b ; getint( a ) , getint( b ) ;

            putint( Solve( a , b ) ) ;

        } else if ( ch == 'A' ) {

            int x ; getint( x ) ;

            int len = getstr( s ) ;

            int t = 0 ;

            build( 0 , len - 1 , t , s ) ;

            Insert( x - 1 , t , roof ) ;

        } else if ( ch == 'C' ) {

            int a , b ; getint( a ) , getint( b ) ;

            int len = getstr( s ) ;

            -- a , -- b ;

            CHANGE( a , b , 0 , len - 1 , s , roof ) ;

        } else if ( ch == 'D' ) {

            int a , b ; getint( a ) , getint( b ) ;

            for ( int i = a ; i <= b ; ++ i ) {

                Delete( a - 1 , roof ) ;

            }

        }

    }

    return 0 ;

}

你可能感兴趣的:(BZOJ-2105: 增强型LCP(HASH+SBT))