题目链接:https://vjudge.net/problem/POJ-3368
解题思路:
题目给出不降序列,
令f[i] = v[i]==v[i-1]? f[i]+1 : 1;
查询区间f[i]的最大值可以RMQ,都是要对l进行剪切,使得v[l]的值是第一次出现的位置才行.
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long ll;
const int mx = 1e5 + 10;
int n,m,a[mx],Max[mx][20];
int up[mx];
void RMQ(int N)
{
for(int j=1;(1<<j)<=N;j++){
int tmp = 1<<(j-1);
for(int i=1;i+tmp<=N;i++)
Max[i][j] = max(Max[i][j-1],Max[i+tmp][j-1]);
}
}
int find(int x,int k)
{
if(k<=0) return 0;
int len = log(k)/log(2.0);
return max(Max[x][len],Max[x+k-(1<<len)][len]);
}
int main()
{
a[0] = 1e9;
while(scanf("%d",&n)&&n)
{
a[n+1] = 1e9;
scanf("%d",&m);
for(int i=1;i<=n;i++){
scanf("%d",a+i);
if(a[i]==a[i-1]) Max[i][0] = Max[i-1][0] + 1;
else Max[i][0] = 1;
}
for(int i=n;i>=1;i--){
if(a[i]==a[i+1]) up[i] = up[i+1];
else up[i] = i;
}
RMQ(n);
int l,r;
while(m--){
scanf("%d%d",&l,&r);
int ans = min(up[l],r)-l+1;
ans = max(ans,find(up[l]+1,r-up[l]));
printf("%d\n",ans);
}
}
return 0;
}