poj 3368 Frequent values(RMQ)

题意:给出一个非降序的数组,给出Q个询问,每个询问给出起点和终点,问在这个区间中出现频率最多的数字的次数。

思路:这题可以用线段树,不过最近在学RMQ,所以用ST做的。这题的难点在于初始化,初始化后直接套模板就行了,来说说初始化吧。

一个区间会出现三种情况:

1、1111111111111,整个区间都被同一个数字占据,那么直接返回(r-l+1)就行了,

2、1111122222222,整个区间只由开始和结尾两种数字组成,这种情况返回两者中较大的。

3、11111222233333,区间中除了两头的数字还有其他数字,那么就用ST求出最大值就行了。

对于每个数字出现的次数,用两个数组来存,一个数组存到目前为止这个数字出现了几次,另一个数组存这个数字总共出现了几次。呃,讲的不是很清楚,可以看代码。

View Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <queue>
#define  N 100004
using namespace std ;

int a[N] , b[N] , mx[N][22] , dat[N] ;
int n , q ;

int maxs ( int x , int y )
{
    return x > y ? x : y ;
}

void init()
{
    int i , j , m ;
    m = floor( log( (double)n ) / log( 2.0));
    for ( i = 1 ; i <= n ; i++ )
    mx[i][0] = a[i] ;
    for ( i = 1 ; i <= m ; i++ )
    {
        for( j = 1 ; j + ( 1<<(i-1)) - 1 <= n ; j++ )
        mx[j][i] = maxs( mx[j][i-1] , mx[j+(1<<(i-1))][i-1] ) ;
    }
}

int find( int l , int r )
{
    if ( a[r] >= ( r - l + 1 )) return ( r - l + 1);
    int m = maxs( b[l] - a[l] + 1 , a[r] );
    int k = 0 ;
    l = l + b[l] - a[l] + 1;
    r = r - a[r] ;
    if ( l > r ) return m ;
    while( l + ( 1<<k ) < r - ( 1<<k ) +1 ) ++k;
    return maxs( m , maxs( mx[l][k] , mx[r-(1<<k)+1][k] ));
}

int main()
{
    int i , s , e ;

    while( scanf( "%d" , &n ) != EOF )
    {
        if( n == 0 )
        break ;
        scanf( "%d" , &q );
        for( i = 1 ; i <= n ; i++ )
        {
            scanf( "%d" , &dat[i] );
            a[i] = 1 ;
        }
        for( i = 2 ; i <= n ; i++ )
        {
            if( dat[i] == dat[i-1] )
            a[i] = a[i-1] + 1;
        }
        b[n] = a[n] ;
        for ( i = n - 1 ; i >= 1 ; i-- )
        {
            if ( dat[i] == dat[i+1] )
            b[i] = b[i+1] ;
            else
            b[i] = a[i] ;
        }
        init();
        while( q-- )
        {
            scanf( "%d%d" , &s , &e );
            printf( "%d\n" , find( s , e ));
        }
    }
    return 0 ;
}
原文地址:https://www.cnblogs.com/misty1/p/2625141.html