***Frequent values
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 10192 Accepted: 3733
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<cstdio>
#include<cstring>
using namespace std;
int a[200010],num[200010],sum[200010],lt[200010],rt[200010];
int ld[200010][48];
int n,q,l,r,w;
int dp() {
for(int i=0; i<w; i++) {
ld[i][0]=sum[i];
}
for(int i=1; (1<<i)<w; i++)
for(int j=0; j+(1<<i)-1<w; j++) {
ld[j][i]=max(ld[j][i-1],ld[j+(1<<(i-1))][i-1]);
}
}
int find_max(int L,int R) {
if (L > R) return 0;
int k=0;
while((1<<(k+1))<=R-L+1)k++;
return max(ld[L][k],ld[R-(1<<k)+1][k]);
}
void range_coding() {
int p=0,item=0,L=0,S=1;
num[p]=0;
lt[p]=0;
for(int i=1; i<=n; i++) {
if(a[p]==a[i]) {
num[i]=item;
lt[i]=L;
S++;
} else {
for(int j=L; j<i; j++)rt[j]=p;
sum[item]=S;
num[i]=++item;
L=lt[i]=i;
S=1;
}
p++;
}
w=item+1;
}
int main() {
while(~scanf("%d%d",&n,&q)&&n) {
memset(a,0,sizeof(a));
memset(num,0,sizeof(num));
memset(sum,0,sizeof(sum));
memset(ld,0,sizeof(ld));
memset(lt,0,sizeof(lt));
memset(rt,0,sizeof(rt));
for(int i=0; i<n; i++)scanf("%d",&a[i]);
range_coding();
dp();
for(int i=0; i<q; i++) {
scanf("%d%d",&l,&r);
l--;
r--;
if(num[l]==num[r])printf("%d\n",r-l+1);
else {
int ans=0;
int iteml=num[l];
int itemr=num[r];
if(lt[l]<l)iteml++;
if(rt[r]>r)itemr--;
if(iteml>itemr)ans=max(rt[l]-l+1,r-lt[r]+1);
else
ans=max(max(rt[l]-l+1,r-lt[r]+1),find_max(iteml,itemr));
printf("%d\n",ans);
}
}
}
return 0;
}
ps:题解请查《算法竞赛入门经典训练指南》by 刘汝佳
因为是写给自己看的。。。