POJ 3368 Frequent values RMQ
2016-04-20 21:04
477 查看
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. 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 |
题意:
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;
}
相关文章推荐
- 简单的四则运算
- 数的奇偶性
- ACMer博客瀑布流分析
- ACM程序设计大赛题目分类
- ACM网址
- 1272 小希的迷宫
- 1272 小希的迷宫
- hdu 1250 大数相加并用数组储存
- 矩阵的乘法操作
- 蚂蚁爬行问题
- 蚂蚁爬行问题
- 求两个数的最大公约数【ACM基础题】
- 打印出二进制中所有1的位置
- 杭电题目---一只小蜜蜂
- HDOJ 1002 A + B Problem II (Big Numbers Addition)
- 初学ACM - 半数集(Half Set)问题 NOJ 1010 / FOJ 1207
- 初学ACM - 组合数学基础题目PKU 1833
- POJ ACM 1002
- POJ 2635 The Embarrassed Cryptographe
- POJ 3292 Semi-prime H-numbers