题目链接点我
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);
}
}
}