POJ 3368 Frequent values RMQ

Frequent values
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 15996   Accepted: 5822

Description

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.

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

Source

Ulm Local 2007


点击打开题目链接 POJ 3368


题意:

POJ 3368 Frequent values RMQ_第1张图片

RMQ范围最大值,对RMQ不熟悉的同胞可以先看看:点击打开博客链接 POJ 3264

我们对原序列进行转换:

if (num[i] == num[i - 1])
       f[i] = f[i - 1] + 1;
else
       f[i] = 1;
对于每个询问:(L,R) 分成两部分(L, t - 1)、(t, R),t 为从左向右遍历查询区间,第一个不与num[ L - 1 ] 相同的数的位置。

则前半部分就是 t - L 个num[ L - 1 ] ,后半部分为数组 f 在区间(t, R) 的最大值。

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int MAXN = 100000 + 10;
int num[MAXN], f[MAXN], d[MAXN][17];    //2^17 <= MAXN
int N, Q;
//初始化
void RMQ_init()
{
    for (int i = 1; i <= N; i++) d[i][0] =  f[i];
    for (int j = 1; (1 << j) <= N; j++)
    {
        for (int i = 1; i + (1 << j) - 1 <= N; i++)
        {
            d[i][j] = max(d[i][j - 1], d[i + (1 << (j - 1))][j - 1]);
        }
    }
}

int RMQ(int L, int R)
{
    if (L > R) return 0;    //说明查询范围内的值全部相同,此时t=R+1
    int k = 0;                          //结果为t-L
    while ((1 << (k + 1)) <= R - L + 1) k++;
    return max(d[L][k], d[R - (1 << k) + 1][k]);
}

int main()
{
    while (~scanf("%d", &N) && N)
    {
        scanf("%d", &Q);
        for (int i = 1; i <= N; i++)
        {
            scanf("%d", &num[i]);
            if (i == 1)
            {
                f[i] = 1;
                continue;
            }
            if (num[i] == num[i - 1])
            {
                f[i] = f[i - 1] + 1;
            }
            else
            {
                f[i] = 1;
            }
        }
        RMQ_init();
        while (Q--)
        {
            int L, R;
            scanf("%d%d", &L, &R);
            int t = L;              //找 t 的位置
            while (t <= R && num[t] == num[t - 1]) t++;
            int ans = RMQ(t, R);
            ans = max(ans, t - L);
            printf("%d\n", ans);
        }
    }
    return 0;
}


你可能感兴趣的:(ACM,RMQ)