您的位置:首页 > 产品设计 > UI/UE

POJ 3368 Frequent values RMQ

2016-04-20 21:04 477 查看
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

题意:



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