题意:
给出一个非降序排序;每次询问区间(i,j);
给出区间内出现最多的数字出现了几次;
非降序就是一样的数字会连在一起,并且升序;
思路:
看训练指南吧;
ac代码;
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;
const int N = 100000 + 5;
int n,m;
int value[N], Count[N], num[N], left[N], right[N];
int d[N][20];
void RMQ_init(int n) {
for(int i = 1; i < n; i++) {
d[i][0] = Count[i];
}
for(int j = 1; (1 << j) < n; j++) {
for(int i = 1; i + (1 << j) < n; i++) {
d[i][j] = max(d[i][j - 1], d[i + (1<<(j - 1))][j - 1]);
}
}
}
int RMQ(int l, int r) {
if(l > r)
return 0;
int k = 0;
while((1 << (k + 1)) <= r - l + 1) k++;
return max(d[l][k], d[r - (1 << k) + 1][k]);
}
int main() {
while(scanf("%d",&n) && n) {
scanf("%d",&m);
int tmp[N];
int t = 1, c = 1, l = 1;
for(int i = 1; i <= n; i++) {
scanf("%d",&tmp[i]);
}
for(int i = 1; i <= n; i++) {
if(i == n || tmp[i] != tmp[i + 1]) {
num[i] = t;
Count[t] = c;
left[t] = l;
right[t++] = i;
c = 1;
l = i + 1;
}
else {
num[i] = t;
c++;
}
}
RMQ_init(t);
while(m--) {
int l,r,res;
scanf("%d%d",&l,&r);
if(num[l] == num[r]) {
res = r - l + 1;
}
else{
int L = num[l] + 1;
int R = num[r] - 1;
int tmp = RMQ(L, R);
res = max(r - left[R + 1] + 1, max(right[L - 1] - l + 1,tmp));
}
printf("%d\n",res);
}
}
}