UVA11235

#include <iostream>
#include <string>
#include <string.h>
#include <math.h>
#include <cmath>
#include <stdio.h>
#include <vector>
#include <stdlib.h>
#include <algorithm>
#include <set>
#include <map>
#include <queue>


using namespace std ;

typedef long long LL ;

const int  maxn = 100008 ;
int  _id[maxn] , _left[maxn] , _right[maxn]  , a[maxn] ;
int  dp[maxn][28] ;
int  n ;
vector<int> C ;

void RMQ_init(){
     int n = C.size() ;
     for(int i = 0 ; i < n ; i++) dp[i][0] = C[i] ;
     for(int j = 1 ; (1<<j) <= n ; j++){
          for(int i = 0 ; i + (1<<j) -1 < n ; i++){
               dp[i][j] = max(dp[i][j-1] , dp[i+ (1<<(j-1)) ][j-1]) ;
          }
     }
}

int  RMQ_ask(int L , int R){
     int k = 0 ;
     while((1<<(k+1)) <= R - L + 1)  k++ ;
     return max(dp[L][k] , dp[R - (1<<k) + 1][k]) ;
}

int  main(){
     int q , i  , k  , re ;
     while(cin>>n && n){
          cin>>q ;
          for(i = 0 ; i < n ; i++)  scanf("%d" , &a[i]) ;
          C.clear() ;
          re = a[0] ;
          k = 1 ;
          for(i = 1 ; i < n ; i++){
               if(a[i] == re) k++ ;
               else{
                    C.push_back(k) ;
                    k = 1 ;
                    re = a[i] ;
               }
          }
          C.push_back(k) ;
          int idx = 0 ;
          k = C[idx] ;
          int L = 0 ;
          for(i = 0 ; i < n ; i++){
               _id[i] = idx ;
               _left[i] = L ;
               _right[i] = L + C[idx] - 1 ;
               if(--k == 0){
                    L += C[idx] ;
                    k = C[++idx] ;
               }
          }
          RMQ_init() ;
          int l , r ;
          while(q--){
               scanf("%d%d" , &l ,&r) ;
               l-- , r-- ;
               int L = _id[l] , R = _id[r] ;
               if(L == R)  printf("%d\n" , r - l + 1) ;
               else if(L + 1 == R)
                    printf("%d\n" , max(_right[l] - l + 1 , r - _left[r] + 1)) ;
               else{
                    int s = RMQ_ask(L+1 , R-1) ;
                    s = max(s , _right[l] - l + 1) ;
                    s = max(s , r - _left[r] + 1) ;
                    printf("%d\n" , s) ;
               }
          }
     }
     return 0 ;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值