题意: 给你一组数列, 查询区间内有出现次数最多的数的频数
RMQ ,
对于一个区间, 分为两部分, 从 L 开始连续到 T , T + 1 到 R
显然 答案为 MAX (T – L + 1 , RMQ ( T+1, R))
对于 T, 可以先预处理出位置 Pos
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 100000 + 131;
int Pos[maxn];
int Num[maxn];
int d[maxn][30];
int Fun[maxn];
int n, m; void RMQ_init()
{
for(int i = 0; i < n; ++i) d[i][0] = Fun[i];
for(int j = 1; (1<<j) <= n; ++j)
for(int i = 0; i + (1<<j) - 1 < n; ++i)
d[i][j] = max(d[i][j-1], d[i+(1<<(j-1))][j-1]);
} int RMQ(int L, int R)
{
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) != EOF)
{
if(n == 0) break;
scanf("%d",&m);
for(int i = 0; i < n; ++i) scanf("%d",&Num[i]);
for(int i = 0; i < n; ++i)
{
if(i == 0) Fun[i] = 1;
else
{
if(Num[i] == Num[i-1]) Fun[i] = Fun[i-1] + 1;
else Fun[i] = 1;
}
}
//for(int i = 0; i < n; ++i) cout << Fun[i];
//cout <<endl; ////////////////////////
int Now = Num[n-1], pos = n-1;
for(int i = n-1; i >= 0; --i)
{
if(Num[i] == Now)
Pos[i] = pos;
else
{
Now = Num[i];
Pos[i] = i;
pos = i;
}
}
/*for(int i = 0; i < n; ++i) cout << Pos[i];
cout <<endl;*/
//////////////////////////
RMQ_init();
//cout << RMQ(2,5) <<endl;
int l, r;
for(int i = 0; i < m; ++i)
{
scanf("%d%d",&l,&r);
l--, r--;
int t = Pos[l];
//cout << t << endl;
if(t >= r)
{
printf("%d\n",r-l+1);
continue;
}
else
printf("%d\n", max(t-l+1,RMQ(t+1,r)));
}
}
}