Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 10935 | Accepted: 4006 |
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
题目大意:
解题思路:
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int a[100100];
int rt[100100];
int dp[200100][30];
int log2(int x){
int res=0;
while(x){x/=2;res++;}
return res;
}
int main(){
int n,q;
while(~scanf("%d",&n)){
memset(dp,0,sizeof(dp));
memset(rt,0,sizeof(rt));
if(n==0)return 0;
scanf("%d",&q);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
int now=n;
rt[n]=n;
for(int i=n-1;i>=1;i--){
if(a[i]<a[now])now=i;
rt[i]=now;
}
dp[1][0]=1;
for(int i=2;i<=n;i++){
if(a[i]==a[i-1])dp[i][0]=dp[i-1][0]+1;
else dp[i][0]=1;
}
int log2n=log2(n)-1;
for(int i=1;i<=log2n;i++){
for(int j=1;j<=n;j++){
dp[j][i]=max(dp[j][i-1],dp[j+(1<<(i-1))][i-1]);
}
}
while(q--){
int l,r;
scanf("%d%d",&l,&r);
if(rt[l]>=r)printf("%d\n",r-l+1);
else{
int tmp=rt[l]-l+1;
int len=r-rt[l];
int log2len=log2(len)-1;
tmp=max(tmp,max(dp[rt[l]+1][log2len],dp[r-(1<<(log2len))+1][log2len]));
printf("%d\n",tmp);
}
}
}
}