Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 8555 | Accepted: 3081 |
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 integersa1 , ... , 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 qlines 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
#include<iostream>
#include<cstdio>
using namespace std;
const int mm=111111;
int f[mm][22],a[mm],b[mm],c[mm];
int i,j,k,n,q;
void dp()
{
for(i=1;i<=n;++i)f[i][0]=a[i];
for(j=1;(1<<j)<=n;++j)
for(i=1;i+(1<<j)-1<=n;++i)
f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
}
int get(int l,int r)
{
if(a[r]>=r-l+1)return r-l+1;
int m=max(b[l]-a[l]+1,a[r]),k=0;
l=l+b[l]-a[l]+1,r-=a[r];
if(l>r)return m;
while(l+(1<<k)<r-(1<<k)+1)++k;
return max(m,max(f[l][k],f[r-(1<<k)+1][k]));
}
int main()
{
while(scanf("%d",&n),n)
{
scanf("%d",&q);
for(i=1;i<=n;++i)scanf("%d",&c[i]),a[i]=1;
for(i=2;i<=n;++i)
if(c[i-1]==c[i])a[i]+=a[i-1];
for(b[n]=a[n],i=n-1;i>0;--i)
if(c[i+1]==c[i])b[i]=b[i+1];
else b[i]=a[i];
dp();
while(q--)scanf("%d%d",&i,&j),printf("%d\n",get(i,j));
}
return 0;
}