UVA 11235 Frequent values RMQ

                                      Frequent values

You are given a sequence of n integers a1, a2, . . . , an in non-decreasing order. In addition to that, you
are given several queries consisting of indices i and j (1 ≤ i ≤ j ≤ n). For each query, determine the
most frequent value among the integers ai
, . . . , aj.
Input
The input consists of several test cases. Each test case starts with a line containing two integers n and
q (1 ≤ n, q ≤ 100000). The next line contains n integers a1, . . . , an (−100000 ≤ ai ≤ 100000, for each
i ∈ {1, ..., n}) separated by spaces. You can assume that for each i ∈ {1, . . . , n − 1}: ai ≤ ai+1. The
following q lines contain one query each, consisting of two integers i and j (1 ≤ i ≤ j ≤ n), which
indicate the boundary indices for the query.
The last test case is followed by a line containing a single ‘0’.
Output
For each query, print one line with one integer: The number of occurrences of the most frequent value
within the given range.
Note: A naive algorithm may not run in time!
Sample Input
10 3
-1 -1 1 1 1 1 3 10 10 10
2 3
1 10
5 10
0
Sample Output
1
4
3

题意:

  给你n个数,q次询问

  每次询问是l,r之间重复最多的数的次数

题解:

  由于这n个数是升序的,我们将其细分问每个位置上的相同数向左向右延生至最左的位置和最右位置,

  处理了这个,利用RMQ求解,判断最大了

  max(RMQ(righti+1,reftj−1),max(righti−i+1,j−leftj+1))

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
using namespace std ;
typedef long long ll;
const int  N = 100000 + 10;
int a[N],x,q,n,dp[N][20],y,l[N],r[N],h[N];;
void RMQ() {
    for(int i = 1; i <= n; i++) dp[i][0] = r[h[i]] - l[h[i]] + 1;
    for(int i = 1; (1<<i) <= n; i++) {
        for(int j = 1; (j + (1<<i) - 1) <= n; j++) {
            dp[j][i] = max(dp[j][i-1],dp[j + (1<<(i-1))][i-1]);
        }
    }
}
int query(int l,int r) {
    if(l == r) return 1;
    else if(l > r) return 0;
    int k = (int) ((log((double)(r - l + 1))) / log(2.0));
    return max(dp[l][k] , dp[r - (1<<k) + 1][k]);
}
map<int,int> mp;
int main() {
    while(scanf("%d%d",&n, &q) == 2 && n) {
        mp.clear();int cnt = 0;
        memset(h,0,sizeof(h));memset(dp,0,sizeof(dp));
        for(int i = 1; i <= n; i++) {
            scanf("%d",&x);
            if(mp[x]) h[i] = cnt, r[cnt] = i, mp[x]++;
            else h[i] = ++ cnt, l[cnt] = i, r[cnt] = i,mp[x] = 1;
        }
        RMQ();
        for(int i = 1; i <= q; i++) {
            scanf("%d%d",&x,&y);
            if(h[x] == h[y]) printf("%d\n", y - x + 1);
            else
            printf("%d\n",max(query(r[h[x]] + 1, l[h[y]] - 1), max(r[h[x]] - x + 1, y - l[h[y]] + 1)));
        }
    }
    return 0;
}

 

posted @ 2016-01-27 21:56  meekyan  阅读(247)  评论(0编辑  收藏  举报