Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 13288 | Accepted: 4880 |
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
——————————————————————————————————————————————
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstdlib>
#include<cmath>
#define M 100000+10
using namespace std;
int n,m;
int a[M],num[M],lef[M],rig[M],dp[M][20];
vector<int> cnt;
void RMQ_init(const vector<int> &A)
{
int n=A.size();
for(int i=0;i<n;++i) dp[i][0]=A[i];
for(int j=1;(1<<j)<=n;++j){
for(int i=0;i+(1<<j)-1<n;++i){
dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
}
}
}
void RLE()
{
int l=-1;
cnt.clear();
for(int i=0;i<=n;++i){
if(i==0||a[i]>a[i-1]){
if(i>0){
cnt.push_back(i-l);
for(int j=l;j<i;++j){
num[j]=cnt.size()-1;
lef[j]=l;
rig[j]=i-1;
}
}
l=i;
}
}
RMQ_init(cnt);
}
int RMQ(int l,int r)
{
int k = 0;
while((1<<(k+1)) <= r-l+1) k++;
return max(dp[l][k],dp[r-(1<<k)+1][k]);
}
int main()
{
while(~scanf("%d",&n)&&n){
scanf("%d",&m);
for(int i=0;i<n;++i) scanf("%d",&a[i]);
a[n]=a[n-1]+1;//?
RLE();
while(m--){
int l,r,ans;
scanf("%d %d",&l,&r);
l--,r--;
if(num[l]==num[r]) ans=r-l+1;
else{
ans=max(r-lef[r]+1,rig[l]-l+1);
if(num[l]+1<=num[r]-1) ans=max(ans,RMQ(num[l]+1,num[r]-1));
}
printf("%d\n",ans);
}
}
return 0;
}