PKU 3368 Frequent values

PKU 3368 Frequent values
(所有数组下标从1计)计算出原数列中每个数出现次数的数列,并用RMQ预处理
如 a[]={ -1 -1 1 1 1 1 3 10 10 10} 得到 sum[]={ 2 4 1 3 }
用index数组记录a[i]在sum中的下标。index[]={1,1,2,2,2,2,3,4,4,4};
first数组记录每组数据中第一个出现的在a中的下标
first[]={1,3,7,8};

对于每个询问的区间[from,to],首先计算出from to在sum中对应的位置f,t
1、如果f==t,则[from,to]区间中数据是一样的
2、如果f+1=t,则[from,to]区间只有两种数据。
3、如果f+1<t,则[from,to]区间有大于两种数据
#include < iostream >
#include
< vector >
#include
< string >
#include
< cmath >
using   namespace  std;
const   int  maxsize = 100001 ;
int  sum[maxsize],st[maxsize][ 20 ],a[maxsize],index[maxsize],first[maxsize];
void  rmq_init( int  len)
{
    
for ( int  i = 1 ;i <= len;i ++ )
        st[i][
0 ] = sum[i];
    
int  m = floor(log(( double )len) / log( 2.0 ));
    
for ( int  i = 1 ;i <= m;i ++ )
        
for ( int  j = len;j > 0 ;j -- )
        {
            st[j][i]
= st[j][i - 1 ];
            
if (i + ( 1 << (i - 1 )) <= len) st[j][i] = max(st[j][i],st[j + ( 1 << (i - 1 ))][i - 1 ]);
        }
}
int  query( int  l, int  r)
{
    
int  m = floor(log(( double )(r - l + 1 )) / log( 2.0 ));
    
return  max(st[l][m],st[r - ( 1 << m) + 1 ][m]);
}
int  solve( const   int   &  from, const   int   &  to)
{
    
int  f = index[from],t = index[to];
    
if (f == t)  return  to - from + 1 ;
    
else   if (f + 1 == t)  return  max(first[t] - from,to - first[t] + 1 );
    
else
    {
        
int  res;
        res
= max(first[f + 1 ] - from,to - first[t] + 1 );
        res
= max(res,query(f + 1 ,t - 1 ));
        
return  res;
    }
}

int  main()
{
    
int  from,to;
    
int  n,q;
    
int  len;
    
while (scanf( " %d " , & n) != EOF)
    {
        
if (n == 0 break ;
        scanf(
" %d " , & q);
        a[
0 ] = INT_MAX;
        
        len
= 0 ;
        memset(sum,
0 , sizeof (sum));
        
for ( int  i = 1 ;i <= n;i ++ )
        {
            scanf(
" %d " , & a[i]);
            
if (a[i] == a[i - 1 ])
            {
                index[i]
= len;
                sum[len]
++ ;
            }
            
else
            {
                index[i]
=++ len;
                sum[len]
= 1 ;
                first[len]
= i;
            }
        }
        rmq_init(len);
        
while (q -- )
        {
            scanf(
" %d%d " , & from, & to);
            printf(
" %d\n " ,solve(from,to));
        }
    }
}


你可能感兴趣的:(PKU 3368 Frequent values)