美文网首页信息学竞赛题解(IO题解)
2724: [Violet 6]蒲公英(分块)

2724: [Violet 6]蒲公英(分块)

作者: acccccc | 来源:发表于2018-10-17 12:08 被阅读0次

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

大意:区间众数,强制在线。至于题解,Violet6的解题报告已经够详细的了,就不班门弄斧了额。

代码(我写的是第二种写法O(n sqrt(n) log n),结果无限TLE,在N次常数优化之后终于AC了饿):

#include <cstdio>

#include <algorithm>

#include <cstring>

#include <cmath>

 

using namespace std ;

 

#define rep( i , x ) for ( int i = 0 ; i ++ < x ; )

#define MAXN 40100

#define inf 0x7fffffff

#define MAXB 410

#define check( ch ) ( ch >= '0' && ch <= '9' )

 

void getint( int &t ) {

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

    t = ch - '0' ;

    for ( ch = getchar(  ) ; check( ch ) ; ch = getchar(  ) ) {

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

    }

}

 

int w[ 20 ] ;

 

void putint( int t ) {

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

        w[ 0 ] = 0 ;

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

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

    }

    putchar( '\n' ) ;

}

 

struct saver {

    int v , t ;

    bool operator < ( const saver &a ) const {

        return v < a.v || ( v == a.v && t < a.t ) ;

    }

    bool operator == ( const saver &a ) const {

        return v == a.v && t == a.t ;

    }

    bool operator > ( const saver &a ) const {

        return v > a.v || ( v == a.v && t > a.t ) ;

    }

} b[ MAXN ] ;

 

int N , first[ MAXN ] , last[ MAXN ] , Mn ;

 

saver make( int v , int t ) {

    saver u ;

    u.v = v , u.t = t ;

    return u ;

}

 

int Lower( int l , int r , saver v ) {

    l -- , ++ r ;

    while ( r - l > 1 ) {

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

        if ( b[ mid ] < v ) l = mid ; else r = mid ;

    }

    return r ;

}

 

int Upper( int l , int r , saver v ) {

    l -- , ++ r ;

    while ( r - l > 1 ) {

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

        if ( b[ mid ] > v ) r = mid ; else l = mid ;

    }

    return r ;

}

 

int COUNT( int l , int r , int v , int L , int R ) {

    return Upper( L , R , make( v , r ) ) - Lower( L , R , make( v , l ) ) ;

}

 

int n , m , M , a[ MAXN ] ;

 

int Begin[ MAXB ] , End[ MAXB ] , Ans[ MAXB ][ MAXB ] ;

 

void INIT(  ) {

    int ret = int( sqrt( n ) ) ;

    rep( i , ret ) {

        Begin[ i ] = ( i - 1 ) * ret + 1 ;

        End[ i ] = i * ret ;

    }

    if ( ret * ret < n ) {

        M = ret + 1 ;

        Begin[ M ] = ret * ret + 1 ;

        End[ M ] = n ;

    } else M = ret ;

    rep( i , M ) {

        int ans , rec = - inf ;

        for ( int j = i ; j <= M ; ++ j ) {

            for ( int k = Begin[ j ] ; k <= End[ j ] ; ++ k ) {

                int cnt = COUNT( Begin[ i ] , k , a[ k ] , first[ k ] , last[ k ] ) ;

                if ( cnt > rec || ( cnt == rec && a[ k ] < ans ) ) {

                    ans = a[ k ] , rec = cnt ;

                }

            }

            Ans[ i ][ j ] = ans ;

        }

    }

}

 

int Query( int l , int r ) {

    int ans = 0 , rec = - inf , L , R , ret = int( sqrt( n ) ) ;

    L = ( l - 1 ) / ret + 1 , R = ( r - 1 ) / ret + 1 ;

    if ( L + 1 <= R - 1 ) {

            if ( ans == Ans[ L + 1 ][ R - 1 ] ) return ans ;

            int cnt = COUNT( l , r , Ans[ L + 1 ][ R - 1 ] , 1 , N ) ;

            if ( cnt > rec || ( cnt == rec && Ans[ L + 1 ][ R - 1 ] < ans ) ) {

                rec = cnt , ans = Ans[ L + 1 ][ R - 1 ] ;

            }

        }

    if ( L == R ) {

        for ( int i = l ; i <= r ; ++ i ) {

            if ( a[ i ] == ans ) continue ;

            int cnt = COUNT( l , r , a[ i ] , first[ i ] , last[ i ] ) ;

            if ( cnt > rec || ( cnt == rec && a[ i ] < ans ) ) {

                rec = cnt , ans = a[ i ] ;

            }

        }

    } else {

        for ( int i = l ; i <= End[ L ] ; ++ i ) {

            if ( a[ i ] == ans ) continue ;

            int cnt = COUNT( l , r , a[ i ] , first[ i ] , last[ i ] ) ;

            if ( cnt > rec || ( cnt == rec && a[ i ] < ans ) ) {

                rec = cnt , ans = a[ i ] ;

            }

        }

        for ( int i = Begin[ R ] ; i <= r ; ++ i ) {

            if ( a[ i ] == ans ) continue ;

            int cnt = COUNT( l , r , a[ i ] , first[ i ] , last[ i ] ) ;

            if ( cnt > rec || ( cnt == rec && a[ i ] < ans ) ) {

                rec = cnt , ans = a[ i ] ;

            }

        }

    }

    return ans ;

}

 

int main(  ) {

    getint( n ) , getint( m ) ;

    rep( i , n ) {

        getint( a[ i ] ) ;

        b[ i ].v = a[ i ] , b[ i ].t = i ;

    }

    N = n + 2 ;

    b[ n + 1 ].v = 0 , b[ n + 1 ].t = 0 ;

    b[ N ].v = inf , b[ N ].t = inf ;

    sort( b + 1 , b + N + 1 ) ;

    for ( int i = 0 ; i ++ < N ; ) {

        if ( i == 1 || b[ i ].v != b[ i - 1 ].v ) Mn = i ;

        first[ b[ i ].t ] = Mn ;

    }

    for ( int i = N ; i ; -- i ) {

        if ( i == N || b[ i ].v != b[ i + 1 ].v ) Mn = i ;

        last[ b[ i ].t ] = Mn ;

    }

    INIT(  ) ;

    int ans = 0 ;

    while ( m -- ) {

        int l , r ; getint( l ) , getint( r ) ;

        l = ( l + ans - 1 ) % n + 1 , r = ( r + ans - 1 ) % n + 1 ;

        if ( l > r ) swap( l , r ) ;

        putint( ans = Query( l , r ) ) ;

    }

    return 0 ;

}

相关文章

网友评论

    本文标题:2724: [Violet 6]蒲公英(分块)

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