HDU1806--Frequent values(RMQ)

题目链接点我

Frequent values

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1975    Accepted Submission(s): 764


Problem 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

Hint

A naive algorithm may not run in time!

题意:输入有多组,给你一个n,代表大小为n的非降序数组,n为0时程序结束,然后有q次询问,每次询问给出一个区间,让你求出这个区间出现最多值的次数。

思路:先对已知的n个数处理一下,处理后的数组我们叫c数组:

-1 -1 1 1 1 1 3 10 10 10
1 2 1 2 3 4 1 1 2 3

比如我们查询[5, 10]区间,我们只要在c数组中找到第一个为1的位置,这时为7,那么答案就是ans = max(7-5,RMQ(7, 10 ) ),不明白的可以多测几组数据。

#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
const int maxn = 1e5+5;
int n, q, x, y, a[maxn], c[maxn], dp[maxn][20];
void ST()
{
    for(int i = 1; i <= n; i++) dp[i][0] = c[i];
    for(int j = 1; (1 << j) <= n; j++)
        for(int i = 1; i + (1 << j) - 1 <= n; i++)
            dp[i][j] = max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
}
int RMQ(int l, int r)
{
    if(l > r) return 0; 
    int k = (int)(log(r - l + 1.0) / log(2.0));
    return max(dp[l][k], dp[r-(1<<k)+1][k]);
}
int main()
{
    while(~scanf("%d",&n) && n)
    {
        scanf("%d", &q);
        for(int i = 1; i <= n; i++) scanf("%d",&a[i]);

        c[1] = 1;
        for(int i = 2; i <= n; i++)
        {
            if(a[i] == a[i-1]) c[i] = c[i-1] + 1;
            else c[i] = 1;
        }

        ST();
        while(q--)
        {
            scanf("%d%d", &x, &y);
            int k = x;
            while(c[k] != 1 && k <= y) k++;
            int ans = max(k-x,RMQ(k,y));
            printf("%d\n", ans);
        }
    }

}

猜你喜欢

转载自blog.csdn.net/sugarbliss/article/details/81118973