链接的话是没有的,我是拿的洛咕的remote judge交的。
做之前一定要读好题面。
注意到是非减的。便由此可以,可以将连续的一段(or 一个)数字,压成一个数字。
然后再在上面处理问题。差不多类似分了个块吧。
然后这样的话,我们便只需要跑rmq就可以了。
对于块内,直接左右镶件。对于块见,使用数据结构维护,
然后因为是静态rmq,所以使用st表就比较优了。
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using std::max;
const int maxn=101000;
int base[maxn];
int log[maxn];
int belong[maxn],id;
int l[maxn],r[maxn];
int st[maxn][22];
void init(int n)
{
id=0;
int now=-0x7fffffff; l[0]=0,id=0;base[n+1]=0x7fffffff;
for(int i=1;i<=n+1;i++)
{
if(base[i]!=now)
{
r[id++]=i-1;
l[id]=i;
now=base[i];
}
belong[i]=id;
}
for(int i=1;i<id;i++) st[i][0]=r[i]-l[i]+1;
for(int i=1;i<=log[id-1];i++)
for(int j=1;j+(1<<i)-1<id;j++)
st[j][i]=max(st[j][i-1],st[j+(1<<i-1)][i-1]);
return ;
}
int check(int L,int R)
{
if(L>R) return 0;
if(L==R) return r[L]-l[R]+1;
int len=log[R-L+1];
return max(st[L][len],st[R-(1<<len)+1][len]);
}
int main()
{
for(int i=2;i<maxn;i++) log[i]=log[i>>1]+1;
int n,q;
scanf("%d",&n);
while(n)
{
scanf("%d",&q);
for(int i=1;i<=n;i++) scanf("%d",&base[i]);
init(n);
int a,b;
for(int i=1;i<=q;i++)
{
scanf("%d%d",&a,&b);
if(belong[a]==belong[b])
printf("%d\n",b-a+1);
else
{
int ans=check(belong[a]+1,belong[b]-1);
ans=max(ans,max(r[belong[a]]-a+1,b-l[belong[b]]+1));
printf("%d\n",ans);
}
}
scanf("%d",&n);
}
}