poj3368(RMQ——ST)

时间:2023-03-09 05:46:24
poj3368(RMQ——ST)
Frequent values
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 16543   Accepted: 5985

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


分析
因为题上说是有序的,就可以求一样的数的数量,再来使用RMQ
开始我也不会做,看了别人的写的,思路还放不开
还记得以前求众数只会用桶排序,现在想起来实在可笑,但是路还很长
AC代码
 #include<cstdio>
#include<iostream>
#include<cmath>
#define MAX 100010
using namespace std;
int f[MAX][];
int num[MAX];
int sum[MAX];
int n,Q,ans,a,b;
int _max(int a,int b)
{
return a>b?a:b;
}
void ST()
{
for(int i=;i<=n;i++)
f[i][]=sum[i];
int k=log((double)(n+))/log(2.0);
for(int i=;i<=k;i++)
for(int j=;j+(<<i)<=n+;j++)//n+1
f[j][i]=_max(f[j][i-],f[j+(<<(i-))][i-]);
}
int RMQ_Query(int l,int r)
{
if(l>r)return ;
int k=log((double)(r-l+))/log(2.0);
return _max(f[l][k],f[r-(<<k)+][k]);//r-(1<<k)一定要+1
}
int main()
{
while(scanf("%d",&n)!=EOF,n)
{
scanf("%d",&Q);
for(int i=;i<=n;i++)
{
scanf("%d",num+i);
if(i==)
{
sum[i]=;
continue;
}
if(num[i]==num[i-])
sum[i]=sum[i-]+;
else sum[i]=;
}
ST();
while(Q--)
{
scanf("%d%d",&a,&b);
if(a==b||num[a]==num[b])
{
cout<<b-a+<<endl;
continue;
}
int t=a;
while(num[t]==num[t-]&&t<=b)//t 必须小于 b
t++;
int cnt=RMQ_Query(t,b);
ans=_max(cnt,t-a);
printf("%d\n",ans);
}
}
return ;
}